IBM Guardium Data Protection 12.2.2, and 12.1 could allow a remote attacker to execute arbitrary commands due to improper neutralization of special elements used in an OS command.
IBM Guardium Data Protection 12.2.2, and 12.1 could allow a remote attacker to delete arbitrary files due to improper limitation of a pathname to a restricted directory.
IBM Guardium Data Protection 12.2.2, and 12.1 could allow a remote attacker to execute arbitrary SQL commands due to improper neutralization of special elements used in an SQL command.
IBM Guardium Data Protection 12.2 is vulnerable to a SQL injection vulnerability in the Load Balancer Groups component. An unauthenticated user can inject SQL statements through the Load Balancer Servlet endpoint, potentially resulting in unauthorized access to data and impact to the confidentiality, integrity, and availability of the affected system.
IBM Guardium Data Protection 12.2 is vulnerable to insecure deserialization in the Quartz JDBC job store. An authenticated attacker could exploit this vulnerability to execute arbitrary code on the affected system.
IBM Guardium Data Protection 12.2 is vulnerable to a SQL injection vulnerability in the New Query Builder REST Processor. A low-privileged authenticated user can inject SQL statements through the newQueryBuilder REST endpoint, potentially resulting in unauthorized access to data and impact to the confidentiality, integrity, and availability of the affected system.
IBM Guardium Data Protection 12.2 could allow an authenticated user to execute arbitrary commands with low user privileges on the system due to improper validation of user supplied input.
IBM Guardium Data Protection 12.2 is vulnerable to a SQL injection vulnerability in the Analytic Grid Service Handler. A low-privileged authenticated user can inject SQL statements through the analytic cases grid endpoint, potentially resulting in unauthorized access to sensitive data and impact to the confidentiality, integrity, and availability of the affected system.
IBM Guardium Data Protection 12.2 is vulnerable to a command injection vulnerability in the import remotelogconfig file CLI command. A highly privileged authenticated user can inject shell commands through the filename parameter, potentially resulting in arbitrary command execution with root privileges and impact to the confidentiality, integrity, and availability of the affected system.
IBM Guardium Data Protection 12.2 is vulnerable to OS command injection in the Universal Connector plugin upload functionality. A privileged authenticated attacker can provide a malicious filename that is incorporated into a shell command executed by the application, potentially resulting in arbitrary command execution with root-level privileges.
IBM Guardium Data Protection 12.2 is vulnerable to a command injection vulnerability in the create csr wildcard CLI command. An authenticated privileged CLI user can inject arbitrary shell commands through the alias input, resulting in command execution with root privileges.
IBM Guardium Data Protection 12.2 is vulnerable to a hardcoded credentials vulnerability in the hardwareassess/obstore binaries. A low-privileged authenticated user can recover hardcoded product master secrets, potentially resulting in unauthorized access to the internal database and compromise of sensitive system information.
The fix released in jackson-core 2.18.6 and 2.21.1 for CVE-2026-18401 (GHSA-72hv-8253-57qq, number length constraint bypass in the non-blocking parser) is incomplete. This record covers the remaining bypass.
The earlier fix wired validateIntegerLength() into a new setIntLength() helper and invoked it wherever the integer portion of a number is decided: a terminator byte arrives, a '.' or 'e'/'E' is seen, or input ends inside a fully buffered value. It was not invoked on the attacker-relevant path where the parser runs out of input while still inside the MINORNUMBERINTEGERDIGITS minor state and returns NOTAVAILABLE to the caller.
As a result, an attacker who streams JSON to a non-blocking parser in many small chunks, without ever sending a terminator byte, keeps the parser inside MINORNUMBERINTEGERDIGITS indefinitely. textBuffer.expandCurrentSegment() grows the accumulator on every chunk while validateIntegerLength() is never called. The accumulator is bounded only by maxStringLength (20 MiB by default) rather than by maxNumberLength (1000 by default), an amplification of roughly 20,000x over the documented limit. Because Java char values occupy two bytes, a single connection can be driven to approximately 40 MiB of heap before the validator finally fires when the value completes.
The equivalent fraction-path code is correct: finishFloatFraction() calls setFractLength() before its NOTAVAILABLE return. The missing call affects the integer-digit paths in startPositiveNumber(), startNegativeNumber() and finishNumberIntegralPart() in NonBlockingUtf8JsonParserBase.
Impact: reactive frameworks such as Spring WebFlux/Reactor, Quarkus, Helidon and Vert.x feed inbound HTTP or gRPC bytes to the async parser as they arrive, which is precisely the chunked-feed shape required. Operators who set StreamReadConstraints.maxNumberLength expecting it to cap memory per number value do not get that guarantee; memory accumulates per concurrent connection and attacker-controlled concurrency can exhaust the JVM heap. The synchronous parsers (UTF8StreamJsonParser, ReaderBasedJsonParser) and the async parser operating on complete input are not affected.
Exploitation requires only the ability to stream data to a parsing endpoint; no privileges or user interaction are needed.
This issue affects com.fasterxml.jackson.core:jackson-core from version 2.15.0 through 2.18.7, and from 2.19.0 through 2.21.3, and tools.jackson.core:jackson-core from 3.0.0 through 3.1.3. Versions prior to 2.15.0 are not affected, because StreamReadConstraints -- which defines the maxNumberLength setting -- was first introduced in jackson-core 2.15.0, so no such constraint exists to be bypassed in earlier releases. Note that GHSA-r7wm-3cxj-wff9 states the affected 2.x range without a lower bound. The 2.22.x and 3.2.x release lines are not affected: those branches were created after the fix commit landed on 2026-05-21 and therefore contain it from their initial releases (2.22.0, tagged 2026-06-03, and 3.2.0, tagged 2026-06-08).
Netty is an asynchronous, event-driven network application framework. Prior to versions 4.1.136.Final and 4.2.16.Final, the Bzip2Decoder handler in Netty's compression codec pipeline is vulnerable to a denial-of-service attack through a malformed bzip2 stream that permanently captures the event-loop thread in an infinite loop. The vulnerability exists in the run-length encoding (RLE) state machine within [Bzip2BlockDecompressor.read()]. This issue has been fixed in versions 4.1.136.Final and 4.2.16.Final.
Summary
A remote, unauthenticated peer can leak one direct ByteBuf per HTTP/2 DATA frame in applications that enable HTTP/2 content decompression via DelegatingDecompressorFrameListener. When a DATA frame is processed for a stream whose decompressor has already been closed, Http2Decompressor.decompress(...) retains the frame buffer but never releases it on the error path, so its reference count never returns to zero. Repeating this over a long-lived HTTP/2 connection exhausts direct memory and crashes the JVM with OutOfMemoryError — a denial of service.
Details
In codec-http2/src/main/java/io/netty/handler/codec/http2/DelegatingDecompressorFrameListener.java, Http2Decompressor.decompress(...) does:
java // around line 433 decompressor.writeInbound(data.retain());
The argument data.retain() is evaluated before writeInbound(...) executes, incrementing the buffer's reference count (refCnt: 1 -> 2). The very first statement of EmbeddedChannel.writeInbound(...) is ensureOpen() (EmbeddedChannel.java:360), which throws ClosedChannelException when the decompressor's internal EmbeddedChannel has already been closed.
When that happens: - the DATA payload has been retain()ed but never entered the pipeline, so the decoder's finally { release() } never runs; - the surrounding catch (Throwable t) block in decompress(...) (around line 451) does not release the extra reference; - the input buffer therefore can never reach refCnt 0, and its (typically direct) memory is leaked.
The decompressor channel is closed on a reachable path: Http2Connection onStreamRemoved → Http2Decompressor.cleanup() → EmbeddedChannel.finishAndReleaseAll() (DelegatingDecompressorFrameListener.java:125-133 and 418-420).
A peer that sends DATA frames for a stream whose decompressor has already been cleaned up (e.g. continuing to send DATA after ENDSTREAM / stream removal) thus leaks one direct ByteBuf per frame.
Affected code: DelegatingDecompressorFrameListener.java, method Http2Decompressor.decompress(...) — the decompressor.writeInbound(data.retain()) call (line ~433) and its catch (Throwable t) block (line ~451), which lacks a data.release() rollback.
Suggested fix: track whether writeInbound succeeded and roll back the extra retain() only when the data never entered the pipeline:
java boolean writeSucceeded = false; try { decompressor.writeInbound(data.retain()); writeSucceeded = true; // pipeline now owns the release if (endOfStream) { decompressor.finish(); } return 0; } catch (Throwable t) { if (!writeSucceeded) { data.release(); // roll back the extra retain(); data never entered pipeline } if (t instanceof Http2Exception) { throw (Http2Exception) t; } throw streamError(stream.id(), INTERNALERROR, t, ...); }
| Case | writeSucceeded | catch action | Reason | |------|:---:|---|---| | ensureOpen() throws (this bug) | false | data.release() | data never entered pipeline | | handler throws internally | true | no release | decoder finally already released | | finish() throws | true | no release | writeInbound already succeeded |
PoC
Reproduced against the official, unmodified netty-codec-http2-4.2.15.Final.jar from Maven Central, using real netty classes and measuring ByteBuf.refCnt() directly (the leaking logic is not mocked).
Reproduction steps:
1. Download the official artifacts and their dependencies from Maven Central (version 4.2.15.Final): netty-common, netty-buffer, netty-transport, netty-resolver, netty-handler, netty-codec-base, netty-codec, netty-codec-http, netty-codec-http2, netty-codec-compression. 2. Build a real Http2Decompressor wrapping a real gzip decoder EmbeddedChannel (ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP)). 3. Close the internal decompressor channel (equivalent to the end state of cleanup() / finishAndReleaseAll()). 4. Encode a real gzip DATA payload with ZlibCodecFactory.newZlibEncoder(GZIP) (refCnt = 1). 5. Call decompress(...) on the closed channel. 6. Observe: writeInbound(...) throws ClosedChannelException at its ensureOpen() entry (EmbeddedChannel.java:360), reached from DelegatingDecompressorFrameListener.java:433; data.refCnt() is now 2. 7. Release once as the frame reader would; refCnt stays at 1 (release() returns false) → leaked.
Observed reference-count trace:
gzipData initial refCnt = 1 decompress -> data.retain() -> refCnt = 2 (retain applied, never rolled back) caller releases once -> refCnt = 1 (release() returns false; not deallocated) => buffer never reaches 0 -> direct memory leaked
Observed exception stack (confirms the leak point):
java.nio.channels.ClosedChannelException at io.netty.channel.embedded.EmbeddedChannel.checkOpen(EmbeddedChannel.java:959) at io.netty.channel.embedded.EmbeddedChannel.ensureOpen(EmbeddedChannel.java:979) at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:360) at io.netty.handler.codec.http2.DelegatingDecompressorFrameListener$Http2Decompressor .decompress(DelegatingDecompressorFrameListener.java:433)
Two notes on the harness (they do not affect the leak mechanism): - The internal channel is closed directly via close() rather than through cleanup(). The end state is identical (channel closed → writeInbound throws at ensureOpen()); the bug depends on "channel closed → retain not rolled back", not on how the channel was closed. - In the isolated harness the rethrown StreamException's root cause shows as NullPointerException because the harness does not initialise an Http2LocalFlowController (a secondary exception reported during channel close). The leak is already sealed at the ClosedChannelException thrown by writeInbound's ensureOpen() (line 360); in a real server with the flow controller initialised, the triggering exception is the ClosedChannelException itself.
A complete self-contained PoC (Verify02DecompressLeak.java, ~150 lines, no test framework) plus the exact javac / java commands can be attached on request.
Impact
- Vulnerability type: uncontrolled resource consumption / memory leak (CWE-401), leading to denial of service. Each crafted DATA frame leaks one (typically direct/off-heap) ByteBuf. - Who is impacted: any server (or client) that enables HTTP/2 content decompression by installing DelegatingDecompressorFrameListener in its HTTP/2 pipeline. - Attacker requirements: remote, unauthenticated. The attacker only needs to send HTTP/2 DATA frames for a stream whose decompressor has been cleaned up (e.g. continue sending DATA after ENDSTREAM). No special server configuration beyond decompression being enabled. - Result: sustained triggering over a long-lived connection exhausts direct memory and crashes the JVM with OutOfMemoryError.
Netty is a network application framework for development of protocol servers and clients. In versions 4.2.0.Final through 4.2.15.Final and 4.1.0.Final through 4.1.135.Final, the SpdyHttpDecoder handler in Netty's SPDY-to-HTTP codec allocates a pooled ByteBuf when processing a client-initiated SYNSTREAM frame with FLAGFIN=0 and stores the partially constructed FullHttpRequest in messageMap; when the remote peer sends RSTSTREAM for that stream or the accumulated content exceeds maxContentLength, the decoder removes the entry but does not release the pooled ByteBuf, causing native memory exhaustion. This issue is fixed in versions 4.1.136.Final and 4.2.16.Final.
Summary Netty SPDY header decoding continues inflating zlib-compressed header blocks after the raw header parser has already exceeded maxHeaderSize and marked the frame truncated. At commit b2d2137c4404af425bf9d5d601a62576f5c06925, a 12,253-byte compressed SPDY header block can declare and inflate a 12 MiB header-name field with maxHeaderSize=16, forcing compression-amplified decode and skip work in a reachable SpdyFrameCodec pipeline.
PoC poc.zip
run with: bash bash ./poc/run.sh expected output: text NETTYSPDYZLIBDECODEDAFTERLIMITTRIGGERED compressedbytes=12253 declarednamelength=12582912 maxheadersize=16 truncated=true invalid=false
The fingerprint means the compressed input was fully consumed while the raw header parser ended with truncated=true and invalid=false after processing the oversized decoded name. That specific state distinguishes this bug from a generic setup failure: the maxHeaderSize guard fired, but the zlib/raw decode path still inflated and skipped the full 12 MiB declared name.
Impact A remote unauthenticated peer that can speak SPDY to a Netty pipeline containing SpdyFrameCodec can send a small compressed HEADERS block that expands into much larger raw header data after the configured maxHeaderSize limit has already been exceeded. The attack requires a reachable SPDY codec, ordinary transport setup such as TCP and optional TLS, and no independent compressed-frame-size or connection-rate limit ahead of SpdyFrameCodec. The satisfied protocol guards are straightforward: the HEADERS frame uses a nonzero stream id and length >= 4, the decoder factory selects the zlib decoder, the payload uses the SPDY dictionary, and the raw block appends a zero-length value so the already-truncated frame reaches ENDHEADERBLOCK. The user-visible effect is denial of service through compression-amplified CPU and allocation churn.
Summary Netty's SPDY SETTINGS decoder accepts a peer-declared SETTINGS entry count up to the 24-bit frame-length limit and materializes every unique setting ID in DefaultSpdySettingsFrame without an implementation-level count cap. A remote SPDY/3.1 peer can send one syntactically valid roughly 2 MiB SETTINGS frame that creates 262144 map entries, amplifying network input into heap growth and ordered-map insertion work.
Details Inbound SPDY bytes enter SpdyFrameCodec.decode() and are passed directly to the frame decoder. The decoder reads the peer-controlled flags and 24-bit frame length from the common header, then accepts SETTINGS frames with only length >= 4. For SETTINGS payloads, it reads the peer-controlled numSettings field and validates only that the remaining payload is divisible into 8-byte entries and exactly matches that count. Each accepted entry then supplies an attacker-controlled 24-bit ID and value, and the normal delegate path forwards it into spdySettingsFrame.setValue(). The sink is DefaultSpdySettingsFrame: it backs settings with a TreeMap, checks only that IDs fit the SPDY 24-bit maximum, and inserts a new Setting for each previously unseen ID. There is no count budget between the wire-format count validation and the TreeMap insertion site.
PoC poc.zip
run with bash bash ./poc/run.sh
expected output: text NETTYSPDYSETTINGSCOUNTMAPTRIGGERED settingscount=262144 wirebytes=2097164 approxheapdelta=17692272 firstvalue=1 lastvalue=262144
The NETTYSPDYSETTINGSCOUNTMAPTRIGGERED line means the harness decoded the crafted SETTINGS frame and observed all 262144 peer-selected IDs in the resulting settings map. The wirebytes=2097164, firstvalue=1, and lastvalue=262144 fields distinguish this from a setup failure: they show the exact oversized frame was accepted and fully materialized.
Impact remote unauthenticated network peer that can speak SPDY/3.1 to a Netty pipeline containing SpdyFrameCodec can trigger resource-exhaustion denial of service. The required guards are satisfied by a complete valid SETTINGS frame using the expected SPDY version, a length of 4 + numSettings 8, and IDs within the accepted 24-bit range; the verified PoC uses numSettings=262144 and wirebytes=2097164. On that input, Netty materializes 262144 attacker-controlled entries in a TreeMap-backed DefaultSpdySettingsFrame, with local runs observing about 17-18 MiB of heap growth per decoded frame plus CPU work for ordered-map insertion.
A possible security vulnerability has been identified in Apache Kafka. This requires access to a alterConfig to the cluster resource, or Kafka Connect worker, and the ability to create/modify connectors on it with an arbitrary Kafka client SASL JAAS config and a SASL-based security protocol, which has been possible on Kafka clusters since Apache Kafka 2.0.0 (Kafka Connect 2.3.0). When configuring the broker via config file or AlterConfig command, or connector via the Kafka Kafka Connect REST API, an authenticated operator can set the sasl.jaas.config property for any of the connector's Kafka clients to "com.sun.security.auth.module.LdapLoginModule", which can be done via the producer.override.sasl.jaas.config, consumer.override.sasl.jaas.config, or admin.override.sasl.jaas.config properties. This will allow the server to connect to the attacker's LDAP server and deserialize the LDAP response, which the attacker can use to execute java deserialization gadget chains on the Kafka connect server. Attacker can cause unrestricted deserialization of untrusted data (or) RCE vulnerability when there are gadgets in the classpath.
Since Apache Kafka 3.0.0, users are allowed to specify these properties in connector configurations for Kafka Connect clusters running with out-of-the-box configurations. Before Apache Kafka 3.0.0, users may not specify these properties unless the Kafka Connect cluster has been reconfigured with a connector client override policy that permits them.
Since Apache Kafka 3.9.1/4.0.0, we have added a system property ("-Dorg.apache.kafka.disallowed.login.modules") to disable the problematic login modules usage in SASL JAAS configuration. Also by default "com.sun.security.auth.module.JndiLoginModule,com.sun.security.auth.module.LdapLoginModule" are disabled in Apache Kafka Connect 3.9.1/4.0.0.
We advise the Kafka users to validate connector configurations and only allow trusted LDAP configurations. Also examine connector dependencies for vulnerable versions and either upgrade their connectors, upgrading that specific dependency, or removing the connectors as options for remediation. Finally, in addition to leveraging the "org.apache.kafka.disallowed.login.modules" system property, Kafka Connect users can also implement their own connector client config override policy, which can be used to control which Kafka client properties can be overridden directly in a connector config and which cannot.
A possible arbitrary file read and SSRF vulnerability has been identified in Apache Kafka Client. Apache Kafka Clients accept configuration data for setting the SASL/OAUTHBEARER connection with the brokers, including "sasl.oauthbearer.token.endpoint.url" and "sasl.oauthbearer.jwks.endpoint.url". Apache Kafka allows clients to read an arbitrary file and return the content in the error log, or sending requests to an unintended location. In applications where Apache Kafka Clients configurations can be specified by an untrusted party, attackers may use the "sasl.oauthbearer.token.endpoint.url" and "sasl.oauthbearer.jwks.endpoint.url" configuratin to read arbitrary contents of the disk and environment variables or make requests to an unintended location. In particular, this flaw may be used in Apache Kafka Connect to escalate from REST API access to filesystem/environment/URL access, which may be undesirable in certain environments, including SaaS products.
Since Apache Kafka 3.9.1/4.0.0, we have added a system property ("-Dorg.apache.kafka.sasl.oauthbearer.allowed.urls") to set the allowed urls in SASL JAAS configuration. In 3.9.1, it accepts all urls by default for backward compatibility. However in 4.0.0 and newer, the default value is empty list and users have to set the allowed urls explicitly.