Back to Repositories

Validating Security Features and Non-Executable JSON Processing in google/gson

This test suite validates security-related functionality in the Gson library, focusing on non-executable JSON handling and serialization/deserialization safety features. The tests ensure proper implementation of security measures for JSON processing in Java applications.

Test Coverage Overview

The test suite provides comprehensive coverage of Gson’s security features, particularly focusing on non-executable JSON handling.

  • Tests non-executable JSON serialization with prefix handling
  • Validates deserialization of JSON with non-executable tokens
  • Covers both regular and configured Gson instances
  • Tests primitive value handling with security tokens

Implementation Analysis

The testing approach utilizes JUnit framework with systematic validation of security features.

Key implementation patterns include:
  • Use of GsonBuilder for configuration testing
  • Consistent prefix validation across test cases
  • Integration with BagOfPrimitives test class for data handling
  • Truth assertion library for precise validations

Technical Details

Testing infrastructure includes:

  • JUnit 4 testing framework
  • Google Truth assertion library
  • Gson and GsonBuilder core components
  • Custom test types for primitive handling
  • Before setup annotations for test initialization

Best Practices Demonstrated

The test suite exemplifies robust security testing practices in Java.

  • Systematic test case organization
  • Comprehensive security token validation
  • Clear test method naming conventions
  • Proper test setup and initialization
  • Thorough edge case coverage

google/gson

gson/src/test/java/com/google/gson/functional/SecurityTest.java

            
/*
 * Copyright (C) 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.gson.functional;

import static com.google.common.truth.Truth.assertThat;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.common.TestTypes.BagOfPrimitives;
import org.junit.Before;
import org.junit.Test;

/**
 * Tests for security-related aspects of Gson
 *
 * @author Inderjeet Singh
 */
public class SecurityTest {
  /** Keep this in sync with Gson.JSON_NON_EXECUTABLE_PREFIX */
  private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";

  private GsonBuilder gsonBuilder;

  @Before
  public void setUp() throws Exception {
    gsonBuilder = new GsonBuilder();
  }

  @Test
  public void testNonExecutableJsonSerialization() {
    Gson gson = gsonBuilder.generateNonExecutableJson().create();
    String json = gson.toJson(new BagOfPrimitives());
    assertThat(json)
        .isEqualTo(
            JSON_NON_EXECUTABLE_PREFIX
                + "{\"longValue\":0,\"intValue\":0,\"booleanValue\":false,\"stringValue\":\"\"}");
  }

  @Test
  public void testNonExecutableJsonDeserialization() {
    String json = JSON_NON_EXECUTABLE_PREFIX + "{longValue:1}";
    Gson gson = gsonBuilder.create();
    BagOfPrimitives target = gson.fromJson(json, BagOfPrimitives.class);
    assertThat(target.longValue).isEqualTo(1);
  }

  @Test
  public void testJsonWithNonExectuableTokenSerialization() {
    Gson gson = gsonBuilder.generateNonExecutableJson().create();
    String json = gson.toJson(JSON_NON_EXECUTABLE_PREFIX);
    assertThat(json).isEqualTo(JSON_NON_EXECUTABLE_PREFIX + "\")]}\\u0027\\n\"");
  }

  /**
   * Gson should be able to deserialize a stream with non-exectuable token even if it is created
   * without {@link GsonBuilder#generateNonExecutableJson()}.
   */
  @Test
  public void testJsonWithNonExectuableTokenWithRegularGsonDeserialization() {
    Gson gson = gsonBuilder.create();
    // Note: Embedding non-executable prefix literally is only possible because Gson is lenient by
    // default
    String json =
        JSON_NON_EXECUTABLE_PREFIX + "{stringValue:\"" + JSON_NON_EXECUTABLE_PREFIX + "\"}";
    BagOfPrimitives target = gson.fromJson(json, BagOfPrimitives.class);
    assertThat(target.stringValue).isEqualTo(JSON_NON_EXECUTABLE_PREFIX);
  }

  /**
   * Gson should be able to deserialize a stream with non-exectuable token if it is created with
   * {@link GsonBuilder#generateNonExecutableJson()}.
   */
  @Test
  public void testJsonWithNonExectuableTokenWithConfiguredGsonDeserialization() {
    // Gson should be able to deserialize a stream with non-exectuable token even if it is created
    Gson gson = gsonBuilder.generateNonExecutableJson().create();
    // Note: Embedding non-executable prefix literally is only possible because Gson is lenient by
    // default
    String json =
        JSON_NON_EXECUTABLE_PREFIX
            + "{intValue:2,stringValue:\""
            + JSON_NON_EXECUTABLE_PREFIX
            + "\"}";
    BagOfPrimitives target = gson.fromJson(json, BagOfPrimitives.class);
    assertThat(target.stringValue).isEqualTo(JSON_NON_EXECUTABLE_PREFIX);
    assertThat(target.intValue).isEqualTo(2);
  }
}