Skip to content

Java: Update qhelp: SnakeYaml is safe from version 2.0 - #20018

Merged
owen-mc merged 2 commits into
github:mainfrom
owen-mc:java/snakeyaml-safe-unsafe-deserialization
Jul 21, 2025
Merged

Java: Update qhelp: SnakeYaml is safe from version 2.0#20018
owen-mc merged 2 commits into
github:mainfrom
owen-mc:java/snakeyaml-safe-unsafe-deserialization

Conversation

@owen-mc

@owen-mc owen-mc commented Jul 10, 2025

Copy link
Copy Markdown
Contributor

It was brought to our attention in #19664 that SnakeYaml is not vulnerable to java/unsafe-deserialization as of version 2.0 (released in 2023). This is because all constructors now extend SafeConstructor. We already had an exclusion for constructors which extend SafeConstructor, so the query does not need to be updated. This PR updates the qhelp file.

Copilot AI review requested due to automatic review settings July 10, 2025 15:57
@owen-mc
owen-mc requested a review from a team as a code owner July 10, 2025 15:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR updates the documentation for the java/unsafe-deserialization query to reflect that SnakeYAML is secure by default starting from version 2.0. The change clarifies that the previous vulnerability recommendations only apply to versions before 2.0, since all constructors now extend SafeConstructor in version 2.0 and later.

  • Updates SnakeYAML security status from "No" to "As of version 2.0"
  • Modifies the recommendation to specify it only applies to versions before 2.0

@github-actions

github-actions Bot commented Jul 10, 2025

Copy link
Copy Markdown
Contributor

QHelp previews:

java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.qhelp

Deserialization of user-controlled data

Deserializing untrusted data using any deserialization framework that allows the construction of arbitrary serializable objects is easily exploitable and in many cases allows an attacker to execute arbitrary code. Even before a deserialized object is returned to the caller of a deserialization method a lot of code may have been executed, including static initializers, constructors, and finalizers. Automatic deserialization of fields means that an attacker may craft a nested combination of objects on which the executed initialization code may have unforeseen effects, such as the execution of arbitrary code.

There are many different serialization frameworks. This query currently supports Kryo, XmlDecoder, XStream, SnakeYaml, JYaml, JsonIO, YAMLBeans, HessianBurlap, Castor, Burlap, Jackson, Jabsorb, Jodd JSON, Flexjson, Gson, JMS, and Java IO serialization through ObjectInputStream/ObjectOutputStream.

Recommendation

Avoid deserialization of untrusted data if at all possible. If the architecture permits it then use other formats instead of serialized objects, for example JSON or XML. However, these formats should not be deserialized into complex objects because this provides further opportunities for attack. For example, XML-based deserialization attacks are possible through libraries such as XStream and XmlDecoder.

Alternatively, a tightly controlled whitelist can limit the vulnerability of code, but be aware of the existence of so-called Bypass Gadgets, which can circumvent such protection measures.

Recommendations specific to particular frameworks supported by this query:

FastJson - com.alibaba:fastjson

  • Secure by Default: Partially
  • Recommendation: Call com.alibaba.fastjson.parser.ParserConfig#setSafeMode with the argument true before deserializing untrusted data.

FasterXML - com.fasterxml.jackson.core:jackson-databind

  • Secure by Default: Yes
  • Recommendation: Don't call com.fasterxml.jackson.databind.ObjectMapper#enableDefaultTyping and don't annotate any object fields with com.fasterxml.jackson.annotation.JsonTypeInfo passing either the CLASS or MINIMAL_CLASS values to the annotation. Read this guide.

Kryo - com.esotericsoftware:kryo and com.esotericsoftware:kryo5

  • Secure by Default: Yes for com.esotericsoftware:kryo5 and for com.esotericsoftware:kryo >= v5.0.0
  • Recommendation: Don't call com.esotericsoftware.kryo(5).Kryo#setRegistrationRequired with the argument false on any Kryo instance that may deserialize untrusted data.

ObjectInputStream - Java Standard Library

  • Secure by Default: No
  • Recommendation: Use a validating input stream, such as org.apache.commons.io.serialization.ValidatingObjectInputStream.

SnakeYAML - org.yaml:snakeyaml

  • Secure by Default: As of version 2.0.
  • Recommendation: For versions before 2.0, pass an instance of org.yaml.snakeyaml.constructor.SafeConstructor to org.yaml.snakeyaml.Yaml's constructor before using it to deserialize untrusted data.

XML Decoder - Standard Java Library

  • Secure by Default: No
  • Recommendation: Do not use with untrusted user input.

ObjectMesssage - Java EE/Jakarta EE

  • Secure by Default: Depends on the JMS implementation.
  • Recommendation: Do not use with untrusted user input.

Example

The following example calls readObject directly on an ObjectInputStream that is constructed from untrusted data, and is therefore inherently unsafe.

public MyObject {
  public int field;
  MyObject(int field) {
    this.field = field;
  }
}

public MyObject deserialize(Socket sock) {
  try(ObjectInputStream in = new ObjectInputStream(sock.getInputStream())) {
    return (MyObject)in.readObject(); // BAD: in is from untrusted source
  }
}

Rewriting the communication protocol to only rely on reading primitive types from the input stream removes the vulnerability.

public MyObject deserialize(Socket sock) {
  try(DataInputStream in = new DataInputStream(sock.getInputStream())) {
    return new MyObject(in.readInt()); // GOOD: read only an int
  }
}

References

@JLLeitschuh

Copy link
Copy Markdown
Contributor

@owen-mc

owen-mc commented Jul 11, 2025

Copy link
Copy Markdown
Contributor Author

Good question. The link still seems to work, and to link to SnakeYaml documentation. But it seems the documentation hasn't been updated for the new behaviour since version 2.0. E.g. it still says:

Note: if you want to limit objects to standard Java objects like List or Long you need to use SafeConstructor.

There is a note at the top of the file that "This documentation is very brief and incomplete. Feel free to fix or improve it." The options are to delete the link because it is confusing, or add a note like "(not updated for new behaviour in version 2.0)". I'm leaning towards the latter. What do you think, @JLLeitschuh ?

@JLLeitschuh

Copy link
Copy Markdown
Contributor

The latter sounds reasonable

@jcogs33 jcogs33 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@owen-mc
owen-mc merged commit 472a6b5 into github:main Jul 21, 2025
@owen-mc
owen-mc deleted the java/snakeyaml-safe-unsafe-deserialization branch July 21, 2025 11:22
thoser666 added a commit to thoser666/Vivid that referenced this pull request Sep 10, 2026
…in 2.4.20

Der CodeQL-Fehler ("Kotlin version 2.4.20 is too recent") kam vom
Action-Pin v4.37.9, dessen Default-Bundle 2.26.4 die Kotlin-2.4.20-GA
noch ablehnt — der Issue github/codeql#22404 war zwar am 08.09.
geschlossen (Extractor-PR github/codeql#20018), ausgeliefert wird der
Support aber erst mit Bundle 2.27.0 (09.09.), das codeql-action v4.38.0
als Default trägt. Die gestrige Wächter-Entfernung (b2d92ed) war damit
zu früh — der eigentliche Fix ist der Pin-Bump, kein Wächter.

  • security-codeql.yml: init+analyze auf v4.38.0 (SHA b96794f01…),
    workflow_dispatch-Trigger ergänzt (empirische Validierung ohne Push)
  • security-scorecard.yml + security-snyk.yml: upload-sarif ebenfalls
    auf v4.38.0 — beseitigt die GitHub-Warnung "Not all workflow steps
    that use github/codeql-action use the same version"
  • RELEASE.md: Abschnitt aktualisiert + neue "Bundle-Lag-Lehre"
    (Action-Pin ≠ Bundle-Stand; Prüfpflicht vor künftigen Kotlin-Bumps)
  • test_workflow_security.sh: Notiz durch die präzise Versionskette
    ersetzt (gleiche Version über init/analyze/upload-sarif ist Pflicht)

Empirische Validierung: workflow_dispatch-Lauf auf dem Feature-Branch
bzw. develop muss die Analyse mit Kotlin 2.4.20 grün abschließen.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
thoser666 added a commit to thoser666/Vivid that referenced this pull request Sep 10, 2026
Der empirische Test des v4.38.0-Pins (CodeQL-Run 34509237841) widerlegt
die Release-Notes-Annahme: Auch Bundle 2.27.0 — der neueste released
Stand — lehnt Kotlin 2.4.20 weiterhin ab ("Kotlin version 2.4.20 is
too recent"). Der Extractor-Support (github/codeql#20018, Issue #22404
geschlossen 08.09.) ist upstream gemerged, aber in KEINEM released
Bundle ausgeliefert. Die Wächter-Entfernung b2d92ed war doppelt zu
früh: erst kam die Blockade zurück, dann bewies der Test, dass auch
der neue Bundle-Stand sie nicht hebt.

  • RELEASE.md: Bundle-Lag-Lehre auf den empirischen Befund korrigiert
    (Issue geschlossen ≠ im Bundle ausgeliefert — erst der grüne
    CodeQL-Lauf zählt); v4.38.0-Pins bleiben (aktuellster Stand +
    Mixed-Version-Warnung behoben)
  • scripts/check_codeql_blockade.sh: schlanker advisory Wächter —
    warnt (::warning::), sobald das neueste codeql-action-Bundle >
    2.27.0 ist; neutral bei Netzwerk-/API-Problemen, nie push-blockierend
  • scripts/test_codeql_blockade.sh: Offline-Selbsttest (6 Szenarien:
    alte Kotlin-Version, <= Blockade-Stand, > Blockade-Stand,
    Action-Tag statt Bundle-Tag, kaputte API-Antwort, Dokumentations-
    Pflichten)
  • pre-push.sh: Wächter + Selbsttest verdrahtet (advisory)
  • test_workflow_security.sh: Notiz auf die korrekte Versionskette
    und die Empirie korrigiert

CodeQL bleibt auf develop rot, bis ein Bundle > 2.27.0 erscheint —
jetzt dokumentiert, bewacht und von echten Regressionen unterscheidbar.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants