Safeguard
Open Source

com.google.code.gson: Using Gson Safely in Modern Java

Why the com.google.code.gson group ID looks so odd, what maintenance mode means for the library, and the configuration habits that keep Gson safe in modern Java services.

Safeguard Team
Product
6 min read

The Maven group ID com.google.code.gson is a fossil: it points at Google Code, the hosting service Google shut down in 2016, and Gson has kept the coordinate ever since because changing a group ID breaks every downstream build. The library itself is anything but dead, it sits in millions of classpaths, Android apps, and JVM services, but its odd naming, its official maintenance-mode status, and its one real CVE all deserve a clear-eyed look before you standardize on it for another decade. This is that look.

The coordinates and what the name tells you

Gson's dependency declaration has been stable for fifteen years:

<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.13.1</version>
</dependency>

or for Gradle:

implementation("com.google.code.gson:gson:2.13.1")

There is exactly one artifact that matters, com.google.code.gson:gson, no module zoo, no BOM required. Compare that with the Jackson ecosystem's three group IDs and dozen modules (we cover those in the Jackson Maven coordinates guide) and you see Gson's core appeal: a single small jar with zero required dependencies that turns objects into JSON and back.

Gson gson = new Gson();
String json = gson.toJson(order);
Order back = gson.fromJson(json, Order.class);

Version 2.13.1 shipped in April 2025; the project cut several releases across 2024 and 2025, so "maintenance mode" has not meant "abandoned".

What maintenance mode actually means here

Google's README says it plainly: "Gson is currently in maintenance mode; existing bugs will be fixed, but large new features will likely not be added." For Android specifically, the project itself points newcomers toward Kotlin Serialization or Moshi's codegen, which avoid runtime reflection entirely.

How you should read that depends on where you stand:

  • Existing codebases: keep calm. Bug fixes and releases continue, the API is frozen-stable, and there is no migration deadline. A serialization library with a fixed feature set is closer to "done" than "dying".
  • New greenfield services: it is a fair prompt to evaluate alternatives, especially on Android or Kotlin, where reflection-free serializers are faster and friendlier to R8/ProGuard optimization.
  • Dependency review: maintenance mode plus continued releases from Google is a low-risk profile. The signal to actually watch for is release cadence stopping, which has not happened.

The security record: one CVE, and what it teaches

Gson's advisory history is remarkably short for a library this widespread. The entry that scanners flag is CVE-2022-25647: versions before 2.8.9 were vulnerable to deserialization of untrusted data through the writeReplace() method in internal classes, exploitable for denial of service. The fix is simply upgrading to 2.8.9 or later, which every 2025-era version satisfies by a wide margin.

Why so short a list compared to, say, jackson-databind's gadget-class saga? Architecture. Gson has no equivalent of "default typing": it will not read a class name out of attacker-controlled JSON and instantiate it. The JSON decides values; your code decides types. That design choice removes the entire remote-code-execution-by-gadget category, which is where polymorphic deserializers historically bled.

That said, "no gadget RCE by design" is not "nothing to configure". The residual risks are real:

  1. Polymorphism added by hand. RuntimeTypeAdapterFactory (from gson-extras) reintroduces type names into JSON. If you use it on untrusted input, register an explicit subtype allowlist, never a package-wide net.
  2. Resource exhaustion. Deeply nested or enormous documents are the classic parser DoS. Cap request body sizes at the edge, and keep Gson current, recent releases hardened JsonReader limits and added a Strictness API for spec-conformant parsing.
  3. Lenient parsing surprises. Historically Gson parsed leniently by default (accepting malformed JSON that other parsers reject). Parser differentials between your edge and your service are a known smuggling vector; use the strictness controls so every layer agrees on what a document means.
  4. Reflection on JDK internals. Serializing types you do not own (JDK collections' internals, third-party classes with odd fields) can break across JVM upgrades and leak fields you never meant to expose. Serialize DTOs you define, not domain objects you happen to have.

Practical configuration for services

A defensible default setup for a modern service:

Gson gson = new GsonBuilder()
    .disableHtmlEscaping()        // only if output is never embedded in HTML
    .serializeNulls()             // pick a null policy on purpose, not by accident
    .setStrictness(Strictness.STRICT)
    .create();

And the habits around it:

  • Treat fromJson return values as untrusted input: validate ranges, lengths, and invariants after binding. Gson checks JSON shape, not business rules.
  • Pin the version in one place (a Gradle version catalog or Maven property) so a single bump covers every module.
  • Remember Android's extra wrinkle: reflection-based binding needs ProGuard/R8 keep rules, and current Gson ships default rules, an underrated reason to stay current.

Because Gson arrives transitively through hundreds of libraries (Retrofit converters, Firebase, countless SDKs), most organizations have more copies than they think. An SCA scan with a tool such as Safeguard will inventory which services still carry pre-2.8.9 versions, which is the only version boundary with a CVE attached, and where version skew between direct and transitive pins has crept in.

Gson, Jackson, or Moshi: the thirty-second version

  • Gson: simplest API, zero dependencies, maintenance mode, reflection-based. Fine everywhere, exceptional nowhere.
  • Jackson: fastest and most featureful on the server, huge module ecosystem, larger attack surface and configuration burden.
  • Moshi / Kotlin Serialization: the right answer for Android and Kotlin-first code, codegen instead of reflection, endorsed by Gson's own README.

Switching costs are real but bounded, serialization libraries touch DTO boundaries, not business logic. If you migrate, do it service by service behind contract tests rather than as a big bang.

FAQ

Why is Gson's group ID com.google.code.gson?

Because the project was originally hosted on Google Code, and Maven group IDs are permanent once artifacts are published, changing it would break every build that depends on the old coordinate. The name is historical, not a signal about hosting or maintenance today.

Is Gson deprecated or abandoned?

Neither. Google labels it maintenance mode, bugs get fixed, major new features do not, and releases continued through 2025 (2.13.1 in April 2025). For new Android or Kotlin projects, Google's own guidance suggests Moshi codegen or Kotlin Serialization instead.

Does Gson have known vulnerabilities?

One notable CVE: CVE-2022-25647, a deserialization-related denial of service affecting versions before 2.8.9. All current versions are well past the fix. Gson's design avoids the gadget-class remote-code-execution issues seen in polymorphic deserializers because it never instantiates types named in the JSON itself.

Is com.google.code.gson:gson safe for untrusted input?

Yes, with the standard precautions: keep the version current, cap payload sizes, use strict parsing, validate bound objects, and if you add polymorphic type adapters yourself, restrict them to an explicit allowlist of subtypes.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.