CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-69201

CVE-2026-69201: Path Traversal and Directory Escape in http4s Static Content Services

Alon Barad
Alon Barad
Software Engineer

Sep 16, 2026·8 min read·11 visits

Executive Summary (TL;DR)

Unauthenticated path traversal vulnerability in http4s static services allows reading arbitrary files outside the resource base directory via percent-encoded path separators.

CVE-2026-69201 is a critical directory traversal vulnerability in the http4s Scala library. Affected versions of ResourceService and WebjarService allow attackers to escape the configured resource directory and access arbitrary files on the classpath or filesystem by using percent-encoded path separators. The flaw arises from decoding URL segments prior to validating them against directory escape patterns.

Vulnerability Overview

The vulnerability identified as CVE-2026-69201 is a directory traversal and path escape vulnerability existing within http4s, a popular type-safe, purely functional HTTP library for Scala. This security issue resides in the components responsible for serving static assets, specifically ResourceService and WebjarService. These components allow developers to mount folders from either the system filesystem, classpath, or packaged WebJar libraries and serve them directly over HTTP. In Scala applications built on functional principles, static asset resolution is typically handled by translating incoming URI paths into pure functional streams (fs2.Stream) that pull binary data from the underlying data store.

An unauthenticated remote attacker can exploit this vulnerability to read arbitrary files from the application classpath or underlying system filesystem, subject to the privileges of the JVM process. The flaw occurs because of a disconnect between how the URL-decoding phase operates and how the subsequent path validation phase enforces boundaries. When a request containing percent-encoded path separators is processed, it escapes the designed containment logic of the configured asset folder, allowing traversal past the designated root.

The attack surface is present whenever an application exposes classpath or file system directories using the affected services. Because static assets are typically public-facing, this vulnerability represents a significant risk to confidentiality. An attacker who successfully escapes the resource base directory can extract sensitive resources, configuration files, environment variables, or application binaries. This exposure is exacerbated in modern containerized deployments, where the JVM classpath may contain configuration secrets or internal microservice endpoints that are not intended for public access.

Root Cause Analysis

The root cause of CVE-2026-69201 is located in the sequence of operations used by http4s to process, decode, and validate path segments during static file retrieval. When an incoming HTTP request is received, http4s decomposes the request URI path into individual string segments. The static content serving engines then decode each individual segment to handle URL-encoded characters. This architectural decision—decoding path segments individually prior to path normalization—creates a gap where structural path boundaries are modified after the validation logic has been completed.

Once decoded, the application runs a path traversal validation routine to prevent directory escape. This verification is implemented via a fold operation over the collection of path segments, attempting to resolve each segment against a designated base directory. The validation checks if any decoded path segment is exactly equal to an empty string, a single dot, or a double dot (the parent directory reference).

segments.foldLeft(rootPath) {
  case (_, "" | "." | "..") => throw BadTraversal
  case (path, segment) => path.resolve(segment)
}

The flaw manifests when an attacker supplies a path segment containing a percent-encoded path separator, such as %2F (forward slash) or %5C (backslash). Because the segment parser does not treat %2F as a path separator during initial segmentation, the sequence ..%2Fsecret.txt is treated as a single, indivisible path segment. The validation routine URL-decodes this segment to ../secret.txt before evaluating the pattern match.

When the decoded string ../secret.txt is evaluated against the pattern match, it fails to match "", ".", or "..". Consequently, it bypasses the security restriction and falls through to the default branch, where it is passed directly to the path.resolve(segment) API. Under the hood, Java's native file system path resolution (typically java.nio.file.Path) interprets the decoded slash character, executing a parent-directory traversal and allowing the attacker to escape the designated base directory. Because ClassLoaders or file system APIs interpret directory levels dynamically, resolving a segment containing .. and a slash effectively shifts the operational context upward, rendering the initial path constraints useless.

Code Analysis & Patch Walkthrough

To fully understand the vulnerability, we can examine the specific patch introduced in commit bcd99cdc1342ef58a0f132acb814af06a668a8d3. The fix targets the pattern matching and validation logic inside the foldLeft path traversal check of all static services, including FileService, ResourceService, and WebjarService. The patch alters the traversal check by verifying whether the decoded segment contains any raw path separator characters.

Here is a visual representation of how the exploit bypasses the original validation mechanism compared to the patched logic:

The patched code introduces a guard condition inside the foldLeft processing block. In the fixed version of FileService.scala, ResourceService.scala, and WebjarService.scala, the segment validator is updated to reject any segment containing a slash or backslash character. This prevents the execution of directory traversal commands even when they are nested inside a longer string segment:

// Patched Validation Logic
segments.foldLeft(rootPath) {
  case (_, "" | "." | "..") => throw BadTraversal
  case (_, segment) if segment.contains("/") || segment.contains("\\") =>
    throw BadTraversal
  case (path, segment) => path.resolve(segment)
}

This secondary check is critical because it neutralizes the bypass. If the decoded segment is ../secret.txt, the first case block is skipped, but the second case block matches because the string contains a / character. The system then immediately aborts execution and throws BadTraversal, preventing the native filesystem APIs from ever receiving the unsanitized path traversal sequence.

It is worth noting that while FileService was not directly exploitable in most configurations due to underlying file system constraints, the maintainers applied the patch to all three static content services. This design symmetry ensures that future changes to filesystem adapters or routing backends do not inadvertently reintroduce the path escape vector.

Exploitation Methodology

Exploiting CVE-2026-69201 requires that the target application serves static content and that the deployment environment does not normalize or strip encoded path separators before passing the request to the JVM backend. Some upstream reverse proxies or application gateways may automatically decode %2F to / prior to routing, which would cause http4s to segment the path normally and trigger the standard BadTraversal exception. However, if the proxy is configured to pass the raw URI or if the backend preserves percent-encoded characters, the system is fully vulnerable.

An attacker can construct a payload targeting sensitive files. For Unix-based environments, a GET request targeting /etc/passwd can be formatted as follows:

GET /static/..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd HTTP/1.1
Host: target.local
Accept: */*

If the target application is running on Windows, the attacker can leverage percent-encoded backslashes (%5C) to traverse directories. This is particularly relevant because Windows path resolution supports both forward and backward slashes as directory separators:

GET /static/..%5C..%5C..%5CWindows%5Cwin.ini HTTP/1.1
Host: target.local
Accept: */*

In addition to filesystem access, because ResourceService resolves assets against the classpath, an attacker can extract compiled .class files, application configuration files containing API keys, database credentials (such as application.conf or logback.xml), and other sensitive build artifacts. This makes the vulnerability highly critical in environments that package secret keys or credentials inside their classpath resources.

The absence of public exploit tools or active in-the-wild exploitation reports should not lull security teams into complacency. Due to the high ease of exploitation once the precise path layout is known, automated scanners can easily adapt standard directory traversal payloads to target this flaw. This highlights the importance of proactive defense.

Remediation & Defensive Configuration

The primary remediation for CVE-2026-69201 is to upgrade the http4s dependency to a secure version. For applications running on the 0.23.x release line, the dependency must be updated to at least 0.23.35. For applications utilizing the 1.0.0 milestone releases, the dependency must be updated to 1.0.0-M47 or higher. The dependency update is typically applied in the SBT build file:

// build.sbt update
libraryDependencies += "org.http4s" %% "http4s-blaze-server" % "0.23.35"

If an immediate library upgrade is not feasible, organizations can implement several mitigation strategies at the infrastructure level. The most effective workaround is to configure upstream reverse proxies or Web Application Firewalls (WAFs) to inspect and block requests containing encoded path separators. For example, in an NGINX configuration, administrators can enforce strict URI normalization or reject requests containing %2F or %5C using specific rule definitions:

# NGINX block to reject percent-encoded path separators
if ($request_uri ~* "(%2F|%5C)") {
    return 400;
}

For environments utilizing Apache ModSecurity, a custom rule can be deployed to inspect the raw request URI and deny access when encoded traversal characters are detected:

SecRule REQUEST_URI_RAW "(?i:%2f|%5c)" "id:1000001,phase:1,deny,status:400,msg:'Blocked Path Traversal Attempt'"

Additionally, developers should ensure that application runtimes do not execute with excessive privileges. Restricting the JVM user account to the minimum necessary file permissions will prevent the process from reading sensitive files outside the application context, even if a path traversal vulnerability is successfully exploited.

Fix Analysis (1)

Technical Appendix

CVSS Score
5.9/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
1,200
via Shodan

Affected Systems

http4s static content serving services (ResourceService, WebjarService, FileService)

Affected Versions Detail

Product
Affected Versions
Fixed Version
http4s
http4s
< 0.23.350.23.35
http4s
http4s
>= 1.0.0-M1, < 1.0.0-M471.0.0-M47
AttributeDetail
CWE IDCWE-22
Attack VectorNetwork (AV:N)
CVSS Score5.9 (Medium)
Exploit StatusNone (No active exploits observed)
CISA KEV StatusNot Listed
ImpactConfidentiality High (Unauthenticated Arbitrary File Read)

MITRE ATT&CK Mapping

T1083File and Directory Discovery
Discovery
T1005Data from Local System
Collection
CWE-22
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The software uses external input to construct a pathname that should be within a restricted directory, but it does not properly neutralize sequences such as '..' that can resolve to a location outside of the restricted directory.

References & Sources

  • [1]GitHub Commit
  • [2]Release Version v0.23.35
  • [3]Release Version v1.0.0-M47
  • [4]GitHub Security Advisory
  • [5]Official CVE Record
  • [6]NVD Detail Page

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 2 hours ago•CVE-2026-119282
7.3

CVE-2026-119282: OS Command Injection via Plugin Options in Nx (@nx/maven and @nx/gradle)

An OS command injection and argument injection vulnerability exists in the Nx build system and its official Maven (@nx/maven) and Gradle (@nx/gradle) plugins. When constructing the project dependency graph, the plugins invoke underlying Java build wrappers via subshells while interpolating unsanitized plugin options directly from nx.json into the command arguments. An attacker who supplies a crafted nx.json file via a repository or pull request can execute arbitrary shell commands with the privileges of the user or CI/CD runner invoking any Nx command that computes the project graph.

Amit Schendel
Amit Schendel
4 views•10 min read
•about 3 hours ago•CVE-2026-59978
7.5

CVE-2026-59978: Persistent Denial of Service via Array Injection in AdminNeo

AdminNeo versions 4.6.2 through 5.4.1 contain an improper input validation vulnerability (CWE-20) in the version verification endpoint (?script=version). An unauthenticated remote attacker can submit a crafted HTTP POST request containing an array parameter for 'version', which is serialized into a shared server-side temporary cache file without type checking or authentication. On subsequent requests, the application deserializes this cached array and passes it to cookie() and rawurlencode(), triggering an uncaught fatal TypeError in PHP 8.x environments and causing a persistent 24-hour Denial of Service (DoS) for all users.

Amit Schendel
Amit Schendel
4 views•8 min read
•about 4 hours ago•GHSA-FGXM-5HVV-X4VH
5.3

GHSA-fgxm-5hvv-x4vh: Private Repository Enumeration via Go Module Discovery and HTTP Response Discrepancies in Soft Serve

Charmbracelet Soft Serve versions 0.5.0 through 0.12.2 contain an authorization bypass and observable response discrepancy vulnerability in the HTTP Git server. Remote attackers can determine the existence, exact names, and clone URLs of private repositories by issuing crafted Go remote import path discovery requests (?go-get=1) or by observing differential HTTP status codes across Git Smart HTTP, Dumb HTTP, and Git LFS endpoints.

Alon Barad
Alon Barad
5 views•12 min read
•about 5 hours ago•GHSA-F3FJ-9625-RV3M
5.9

GHSA-f3fj-9625-rv3m: Race Condition in Soft Serve Repository Cache Invalidation

A Time-of-Check to Time-of-Use (TOCTOU) race condition in Charmbracelet Soft Serve versions 0.6.0 through 0.12.2 allows unauthenticated users to retain read access to repositories after their visibility is changed from public to private. The flaw stems from premature cache invalidation in the SetPrivate method prior to committing the visibility update to the underlying database. Concurrent read requests arriving during the database transaction window repopulate the non-expiring in-memory LRU cache with stale public metadata, bypassing access controls across HTTP, SSH, and Git protocols until the server process is restarted.

Alon Barad
Alon Barad
4 views•10 min read
•about 6 hours ago•CVE-2026-119283
7.5

CVE-2026-119283: Unbounded JWE Recipients Array Causes CPU Exhaustion in Authlib joserfc

A resource consumption vulnerability exists in the Authlib joserfc Python library prior to version 1.7.5. When processing JSON Web Encryption (JWE) objects formatted using General JSON Serialization, the library fails to enforce an upper bound on the number of elements within the recipients array. An unauthenticated attacker can supply a JWE containing thousands of recipient entries targeting an RSA key management algorithm, forcing the server to perform an equivalent number of computationally expensive RSA private-key decryption operations per request and exhausting available CPU resources.

Alon Barad
Alon Barad
4 views•9 min read
•about 7 hours ago•CVE-2026-119284
6.9

CVE-2026-119284: Uncontrolled Resource Consumption in joserfc Compact Deserialization

CVE-2026-119284 (GHSA-9pg5-8c7x-5hfx) is an uncontrolled resource consumption vulnerability (CWE-400) in the compact serialization deserialization routines of joserfc prior to version 1.7.6. The library enforced individual segment size limits only after invoking Python's bytes.split(b'.') on untrusted input tokens. By sending oversized compact JWS or JWE tokens, an unauthenticated remote attacker can force the Python interpreter to duplicate and allocate memory for every segment before size validation executes, resulting in memory exhaustion and an Endpoint Denial of Service (DoS).

Amit Schendel
Amit Schendel
8 views•10 min read