{"id":"CVE-2026-69201","aliases":["EUVD-2026-79177","GHSA-crq5-92j2-j7wv"],"status":"published","title":"Http4s: ResourceService and Webjar Service path escape via percent-encoded separators","description":"Http4s is a Scala interface for HTTP services. Prior to 0.23.35 and 1.0.0-M47, ResourceService and WebjarService decode each URL path segment but reject only segments exactly equal to an empty string, a dot, or two dots. A request containing percent-encoded slash or backslash separators can turn an accepted segment into a parent-directory traversal after decoding, allowing access to classpath or WebJar resources outside the configured base when a directory-backed classpath is served and the backend preserves the encoded separator. The patch rejects decoded segments containing slash or backslash in ResourceService and WebjarService, and applies the same guard to the non-exploitable FileService for consistency. This issue is fixed in versions 0.23.35 and 1.0.0-M47.","severity":{"version":"3.1","score":5.9,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-08","score":0.00758,"percentile":0.55476,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-22"],"published":"2026-09-15T19:02:18Z","modified":"2026-10-28T02:30:53Z","fixes":[{"ecosystem":"Maven","package":"org.http4s:http4s-server_2.12","fixed_in":["0.23.35"],"sources":["ghsa","osv"]},{"ecosystem":"Maven","package":"org.http4s:http4s-server_2.13","fixed_in":["0.23.35","1.0.0-M47"],"sources":["ghsa","osv"]},{"ecosystem":"Maven","package":"org.http4s:http4s-server_3","fixed_in":["0.23.35","1.0.0-M47"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"Maven","package":"org.http4s:http4s-server_2.12","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"0.23.34"},{"fixed":"0.23.35"}]}]},{"source":"ghsa","ecosystem":"Maven","package":"org.http4s:http4s-server_2.13","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"0.23.34"},{"fixed":"0.23.35"}]}]},{"source":"ghsa","ecosystem":"Maven","package":"org.http4s:http4s-server_3","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"0.23.34"},{"fixed":"0.23.35"}]}]},{"source":"ghsa","ecosystem":"Maven","package":"org.http4s:http4s-server_3","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.0.0-M1"},{"last_affected":"1.0.0-M46"},{"fixed":"1.0.0-M47"}]}]},{"source":"ghsa","ecosystem":"Maven","package":"org.http4s:http4s-server_2.13","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.0.0-M1"},{"last_affected":"1.0.0-M46"},{"fixed":"1.0.0-M47"}]}]},{"source":"osv","ecosystem":"Maven","package":"org.http4s:http4s-server_2.12","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.23.35"}]}],"versions":["0.10.0-M10","0.15.0","0.15.0a","0.15.1","0.15.10","0.15.10a","0.15.11","0.15.11a","0.15.12","0.15.12a","0.15.13","0.15.13a","0.15.14","0.15.14a","0.15.15","0.15.15a","0.15.16","0.15.16a","0.15.1a","0.15.2","0.15.2a","0.15.3","0.15.3a","0.15.4","0.15.4a","0.15.5","0.15.5a","0.15.6","0.15.6a","0.15.7","0.15.7a","0.15.8","0.15.8a","0.15.9","0.15.9a","0.16.0","0.16.0-M1","0.16.0-M2","0.16.0-M3","0.16.0-RC1","0.16.0-RC2","0.16.0-RC3","0.16.0a","0.16.0a-M1","0.16.0a-M2","0.16.0a-M3","0.16.0a-RC1","0.16.0a-RC2","0.16.0a-RC3","0.16.1","0.16.1a","0.16.2","0.16.2a","0.16.3","0.16.3a","0.16.4","0.16.4a","0.16.5","0.16.5a","0.16.6","0.16.6a","0.17.0","0.17.0-M1","0.17.0-M2","0.17.0-M3","0.17.0-RC1","0.17.0-RC2","0.17.0-RC3","0.17.1","0.17.2","0.17.3","0.17.4","0.17.5","0.17.6","0.18.0","0.18.0-M1","0.18.0-M2","0.18.0-M3","0.18.0-M4","0.18.0-M5","0.18.0-M6","0.18.0-M7","0.18.0-M8","0.18.0-M9","0.18.1","0.18.10","0.18.11","0.18.12","0.18.13","0.18.14","0.18.15","0.18.16","0.18.17","0.18.18","0.18.19","0.18.2","0.18.20","0.18.21","0.18.22","0.18.23","0.18.24","0.18.25","0.18.26","0.18.3","0.18.4","0.18.5","0.18.6","0.18.7","0.18.8","0.18.9","0.19.0","0.19.0-M1","0.19.0-M2","0.19.0-M3","0.19.0-M4","0.20.0","0.20.0-M1","0.20.0-M2","0.20.0-M3","0.20.0-M4","0.20.0-M5","0.20.0-M6","0.20.0-M7","0.20.0-RC1","0.20.1","0.20.10","0.20.11","0.20.12","0.20.13","0.20.14","0.20.15","0.20.16","0.20.17","0.20.18","0.20.19","0.20.2","0.20.20","0.20.21","0.20.22","0.20.23","0.20.3","0.20.4","0.20.5","0.20.6","0.20.7","0.20.8","0.20.9","0.21.0","0.21.0-M1","0.21.0-M2","0.21.0-M3","0.21.0-M4","0.21.0-M5","0.21.0-M6","0.21.0-RC1","0.21.0-RC2","0.21.0-RC3","0.21.0-RC4","0.21.0-RC5","0.21.1","0.21.11","0.21.12","0.21.13","0.21.14","0.21.15","0.21.16","0.21.17","0.21.18","0.21.19","0.21.2","0.21.20","0.21.21","0.21.22","0.21.23","0.21.24","0.21.25","0.21.26","0.21.27","0.21.28","0.21.29","0.21.3","0.21.30","0.21.31","0.21.32","0.21.33","0.21.34","0.21.4","0.21.5","0.21.6","0.21.7","0.21.8","0.21.9","0.22-129-24d065b","0.22-143-49b5a8d","0.22-53-01128f5","0.22-96-55d3184","0.22.0","0.22.0-M1","0.22.0-M2","0.22.0-M3","0.22.0-M4","0.22.0-M5","0.22.0-M6","0.22.0-M7","0.22.0-M8","0.22.0-RC1","0.22.1","0.22.10","0.22.11","0.22.12","0.22.13","0.22.14","0.22.15","0.22.2","0.22.3","0.22.4","0.22.5","0.22.6","0.22.7","0.22.8","0.22.9","0.23.0","0.23.0-M1","0.23.0-RC1","0.23.1","0.23.10","0.23.11","0.23.12","0.23.13","0.23.14","0.23.15","0.23.16","0.23.17","0.23.18","0.23.19","0.23.19-RC1","0.23.19-RC2","0.23.19-RC3","0.23.2","0.23.20","0.23.21","0.23.22","0.23.23","0.23.24","0.23.25","0.23.26","0.23.27","0.23.28","0.23.29","0.23.3","0.23.30","0.23.31","0.23.32","0.23.33","0.23.34","0.23.4","0.23.5","0.23.6","0.23.7","0.23.8","0.23.9"]},{"source":"osv","ecosystem":"Maven","package":"org.http4s:http4s-server_2.13","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.23.35"}]}],"versions":["0.10.0-M10","0.21.0","0.21.0-M1","0.21.0-M2","0.21.0-M3","0.21.0-M4","0.21.0-M5","0.21.0-M6","0.21.0-RC1","0.21.0-RC2","0.21.0-RC3","0.21.0-RC4","0.21.0-RC5","0.21.1","0.21.11","0.21.12","0.21.13","0.21.14","0.21.15","0.21.16","0.21.17","0.21.18","0.21.19","0.21.2","0.21.20","0.21.21","0.21.22","0.21.23","0.21.24","0.21.25","0.21.26","0.21.27","0.21.28","0.21.29","0.21.3","0.21.30","0.21.31","0.21.32","0.21.33","0.21.34","0.21.4","0.21.5","0.21.6","0.21.7","0.21.8","0.21.9","0.22-129-24d065b","0.22-143-49b5a8d","0.22-53-01128f5","0.22-96-55d3184","0.22.0","0.22.0-M1","0.22.0-M2","0.22.0-M3","0.22.0-M4","0.22.0-M5","0.22.0-M6","0.22.0-M7","0.22.0-M8","0.22.0-RC1","0.22.1","0.22.10","0.22.11","0.22.12","0.22.13","0.22.14","0.22.15","0.22.2","0.22.3","0.22.4","0.22.5","0.22.6","0.22.7","0.22.8","0.22.9","0.23.0","0.23.0-M1","0.23.0-RC1","0.23.1","0.23.10","0.23.11","0.23.12","0.23.13","0.23.14","0.23.15","0.23.16","0.23.17","0.23.18","0.23.19","0.23.19-RC1","0.23.19-RC2","0.23.19-RC3","0.23.2","0.23.20","0.23.21","0.23.22","0.23.23","0.23.24","0.23.25","0.23.26","0.23.27","0.23.28","0.23.29","0.23.3","0.23.30","0.23.31","0.23.32","0.23.33","0.23.34","0.23.4","0.23.5","0.23.6","0.23.7","0.23.8","0.23.9"]},{"source":"osv","ecosystem":"Maven","package":"org.http4s:http4s-server_3","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.23.35"}]}],"versions":["0.22.0","0.22.0-M8","0.22.0-RC1","0.22.1","0.22.10","0.22.11","0.22.12","0.22.13","0.22.14","0.22.15","0.22.2","0.22.3","0.22.4","0.22.5","0.22.6","0.22.7","0.22.8","0.22.9","0.23.0","0.23.0-M1","0.23.0-RC1","0.23.1","0.23.10","0.23.11","0.23.12","0.23.13","0.23.14","0.23.15","0.23.16","0.23.17","0.23.18","0.23.19","0.23.19-RC1","0.23.19-RC2","0.23.19-RC3","0.23.2","0.23.20","0.23.21","0.23.22","0.23.23","0.23.24","0.23.25","0.23.26","0.23.27","0.23.28","0.23.29","0.23.3","0.23.30","0.23.31","0.23.32","0.23.33","0.23.34","0.23.4","0.23.5","0.23.6","0.23.7","0.23.8","0.23.9"]},{"source":"osv","ecosystem":"Maven","package":"org.http4s:http4s-server_3","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.0.0-M1"},{"fixed":"1.0.0-M47"}]}],"versions":["1.0.0-M22","1.0.0-M23","1.0.0-M24","1.0.0-M25","1.0.0-M27","1.0.0-M28","1.0.0-M29","1.0.0-M30","1.0.0-M31","1.0.0-M32","1.0.0-M33","1.0.0-M34","1.0.0-M35","1.0.0-M36","1.0.0-M37","1.0.0-M38","1.0.0-M39","1.0.0-M40","1.0.0-M41","1.0.0-M42","1.0.0-M43","1.0.0-M44","1.0.0-M45","1.0.0-M46"]},{"source":"osv","ecosystem":"Maven","package":"org.http4s:http4s-server_2.13","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.0.0-M1"},{"fixed":"1.0.0-M47"}]}],"versions":["1.0.0-M10","1.0.0-M13","1.0.0-M14","1.0.0-M15","1.0.0-M16","1.0.0-M17","1.0.0-M18","1.0.0-M19","1.0.0-M2","1.0.0-M20","1.0.0-M21","1.0.0-M22","1.0.0-M23","1.0.0-M24","1.0.0-M25","1.0.0-M27","1.0.0-M28","1.0.0-M29","1.0.0-M3","1.0.0-M30","1.0.0-M31","1.0.0-M32","1.0.0-M33","1.0.0-M34","1.0.0-M35","1.0.0-M36","1.0.0-M37","1.0.0-M38","1.0.0-M39","1.0.0-M4","1.0.0-M40","1.0.0-M41","1.0.0-M42","1.0.0-M43","1.0.0-M44","1.0.0-M45","1.0.0-M46","1.0.0-M5","1.0.0-M6","1.0.0-M7","1.0.0-M8","1.0.0-M9"]}],"products":[{"vendor":"http4s","product":"http4s"}],"references":[{"url":"https://github.com/http4s/http4s/security/advisories/GHSA-crq5-92j2-j7wv","tags":["x_refsource_CONFIRM","advisory","web"]},{"url":"https://github.com/http4s/http4s/commit/bcd99cdc1342ef58a0f132acb814af06a668a8d3","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/http4s/http4s/releases/tag/v0.23.35","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/http4s/http4s/releases/tag/v1.0.0-M47","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/advisories/GHSA-crq5-92j2-j7wv"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/69xxx/CVE-2026-69201.json","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-69201","tags":["advisory"]},{"url":"https://github.com/http4s/http4s","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-69201","title":"Http4s: ResourceService and Webjar Service path escape via percent-encoded separators","description":"Http4s is a Scala interface for HTTP services. Prior to 0.23.35 and 1.0.0-M47, ResourceService and WebjarService decode each URL path segment but reject only segments exactly equal to an empty string, a dot, or two dots. A request containing percent-encoded slash or backslash separators can turn an accepted segment into a parent-directory traversal after decoding, allowing access to classpath or WebJar resources outside the configured base when a directory-backed classpath is served and the backend preserves the encoded separator. The patch rejects decoded segments containing slash or backslash in ResourceService and WebjarService, and applies the same guard to the non-exploitable FileService for consistency. This issue is fixed in versions 0.23.35 and 1.0.0-M47.","status":"published","published":"2026-09-15T19:02:18.376Z","modified":"2026-09-15T19:21:15.876Z","cvss":[{"version":"3.1","score":5.9,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"medium","assessor":"cna"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T13:50:16.178634Z"}],"euvd":[{"id":"EUVD-2026-79177","description":"Http4s is a Scala interface for HTTP services. Prior to 0.23.35 and 1.0.0-M47, ResourceService and WebjarService decode each URL path segment but reject only segments exactly equal to an empty string, a dot, or two dots. A request containing percent-encoded slash or backslash separators can turn an accepted segment into a parent-directory traversal after decoding, allowing access to classpath or WebJar resources outside the configured base when a directory-backed classpath is served and the backend preserves the encoded separator. The patch rejects decoded segments containing slash or backslash in ResourceService and WebjarService, and applies the same guard to the non-exploitable FileService for consistency. This issue is fixed in versions 0.23.35 and 1.0.0-M47.","status":"published","published":"2026-09-15T19:02:18Z","modified":"2026-09-15T19:21:15Z","cvss":[{"version":"3.1","score":5.9,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"medium"}],"updated_at":"2026-11-02T17:28:17.333425Z"}],"ghsa":[{"id":"GHSA-crq5-92j2-j7wv","title":"Http4s: ResourceService and Webjar Service path escape via percent-encoded separators","description":"The static content handlers `ResourceService` and `WebjarService` URL decode each path segment and then reject only segments that are exactly `\"\"`, `\".\"`, or `\"..\"`.  A percent-encoded separator (`%2F`) lets an attacker smuggle a `../` segment past that filter and escape the configured base, reading resources that should not be public.\n\nOn Windows, a similar attack exists with (`%5C`).\n\n## Impact\n\nDisclosure of classpath or webjar resources outside the configured base.\n\n## Preconditions\n\n- Application uses `ResourceService` (with a non-root base path) or `WebjarService`\n- At least one classpath entry is served from a directory (e.g. `sbt run`, exploded .war)\n- Backend forwards `%2F`/`%5C` without normalizing (e.g., Ember, Blaze)\n\n## Fixes\n\nThe patch rejects any decoded path segment containing `/` (`%2F`) or `\\` (`%5C`) with a `400 Bad Request` in `ResourceService` and `WebjarService`.\n\n`FileService` was not exploitable, but the same guards are applied for consistency and to remove its reliance on path normalization.\n\n## Workarounds\n\n- Deploy as a fat jar, with no filesystem directories on the classpath.\n- Front the service with a proxy that rejects/normalizes `%2F` and `%5C` in the request path.","status":"published","published":"2026-09-15T20:01:12Z","modified":"2026-09-15T20:01:14Z","cvss":[{"version":"3.1","score":5.9,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"medium"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T14:41:17.136201Z"}],"nvd":[{"id":"CVE-2026-69201","description":"Http4s is a Scala interface for HTTP services. Prior to 0.23.35 and 1.0.0-M47, ResourceService and WebjarService decode each URL path segment but reject only segments exactly equal to an empty string, a dot, or two dots. A request containing percent-encoded slash or backslash separators can turn an accepted segment into a parent-directory traversal after decoding, allowing access to classpath or WebJar resources outside the configured base when a directory-backed classpath is served and the backend preserves the encoded separator. The patch rejects decoded segments containing slash or backslash in ResourceService and WebjarService, and applies the same guard to the non-exploitable FileService for consistency. This issue is fixed in versions 0.23.35 and 1.0.0-M47.","status":"published","published":"2026-09-15T19:17:37.423Z","modified":"2026-09-16T20:38:04.943Z","cvss":[{"version":"3.1","score":5.9,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"medium","assessor":"secondary"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T14:12:47.668237Z"}],"osv":[{"id":"CVE-2026-69201","title":"Http4s: ResourceService and Webjar Service path escape via percent-encoded separators","description":"Http4s is a Scala interface for HTTP services. Prior to 0.23.35 and 1.0.0-M47, ResourceService and WebjarService decode each URL path segment but reject only segments exactly equal to an empty string, a dot, or two dots. A request containing percent-encoded slash or backslash separators can turn an accepted segment into a parent-directory traversal after decoding, allowing access to classpath or WebJar resources outside the configured base when a directory-backed classpath is served and the backend preserves the encoded separator. The patch rejects decoded segments containing slash or backslash in ResourceService and WebjarService, and applies the same guard to the non-exploitable FileService for consistency. This issue is fixed in versions 0.23.35 and 1.0.0-M47.","status":"published","published":"2026-09-15T19:02:18.376Z","modified":"2026-10-28T02:30:53.949800132Z","cvss":[{"version":"3.1","score":5.9,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"medium"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T15:45:15.164658Z"},{"id":"GHSA-crq5-92j2-j7wv","title":"Http4s: ResourceService and Webjar Service path escape via percent-encoded separators","description":"The static content handlers `ResourceService` and `WebjarService` URL decode each path segment and then reject only segments that are exactly `\"\"`, `\".\"`, or `\"..\"`.  A percent-encoded separator (`%2F`) lets an attacker smuggle a `../` segment past that filter and escape the configured base, reading resources that should not be public.\n\nOn Windows, a similar attack exists with (`%5C`).\n\n## Impact\n\nDisclosure of classpath or webjar resources outside the configured base.\n\n## Preconditions\n\n- Application uses `ResourceService` (with a non-root base path) or `WebjarService`\n- At least one classpath entry is served from a directory (e.g. `sbt run`, exploded .war)\n- Backend forwards `%2F`/`%5C` without normalizing (e.g., Ember, Blaze)\n\n## Fixes\n\nThe patch rejects any decoded path segment containing `/` (`%2F`) or `\\` (`%5C`) with a `400 Bad Request` in `ResourceService` and `WebjarService`.\n\n`FileService` was not exploitable, but the same guards are applied for consistency and to remove its reliance on path normalization.\n\n## Workarounds\n\n- Deploy as a fat jar, with no filesystem directories on the classpath.\n- Front the service with a proxy that rejects/normalizes `%2F` and `%5C` in the request path.","status":"published","published":"2026-09-15T20:01:12Z","modified":"2026-09-15T20:15:05.103669257Z","cvss":[{"version":"3.1","score":5.9,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"medium"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T15:46:45.28161Z"}]}}
