OSEC-2026-16

See a problem?
Import Source
https://github.com/ocaml/security-advisories/blob/generated-osv/2026/OSEC-2026-16.json
JSON Data
https://api.osv.dev/v1/vulns/OSEC-2026-16
Published
2026-08-20T18:15:00Z
Modified
2026-08-22T11:15:03Z
Severity
  • 8.7 (High) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/S:N/AU:Y/R:A/V:D/RE:M CVSS Calculator
Summary
Path traversal in Cohttp.Path.resolve_local_file
Details

The issue is that the function normalizes the URI path before percent decoding it:

let resolve_local_file ~docroot ~uri =

  let path = Uri.(pct_decode (path (resolve "http" (of_string "/") uri))) in

  ...

Because %2f is decoded after Uri.resolve, encoded separators survive dot-segment normalization. For example, a request path like:

/static/..%2f..%2f..%2fetc/passwd

is normalized as a single encoded segment, then decoded into:

/static/../../../etc/passwd

afterwards.

Timeline

Database specific
{
    "cwe": [
        "CWE-22"
    ],
    "human_link": "https://github.com/ocaml/security-advisories/tree/main/advisories/2026/OSEC-2026-16.md",
    "osv": "https://github.com/ocaml/security-advisories/tree/generated-osv/2026/OSEC-2026-16.json"
}
Credits
    • Sapphire Livingstone - REPORTER
    • Sapphire Livingstone - REMEDIATION_DEVELOPER
    • Anil Madhavapeddy - REMEDIATION_DEVELOPER
    • Anil Madhavapeddy - REMEDIATION_REVIEWER
    • Michael Dales - REMEDIATION_REVIEWER
    • Edwin Torok - REMEDIATION_REVIEWER
    • Patrick Ferris - REMEDIATION_REVIEWER
    • Hannes Mehnert - COORDINATOR

Affected packages

opam / cohttp

Package

Name
cohttp
Purl
pkg:opam/cohttp

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
6.3.0
Type
GIT
Repo
https://github.com/mirage/ocaml-cohttp.git
Events
Introduced
0 Unknown introduced commit / All previous commits are affected
Fixed

Affected versions

0.*
0.9.1
0.9.2
0.9.3
0.9.4
0.9.5
0.9.6
0.9.7
0.9.8
0.9.9
0.9.10
0.9.11
0.9.12
0.9.13
0.9.14
0.9.15
0.9.16
0.10.0
0.10.1
0.11.0
0.11.1
0.11.2
0.12.0
0.13.0
0.14.0
0.15.0
0.15.1
0.15.2
0.16.0
0.16.1
0.17.0
0.17.1
0.17.2
0.18.0
0.18.1
0.18.2
0.18.3
0.19.0
0.19.1
0.19.2
0.19.3
0.20.0
0.20.1
0.20.2
0.21.0
0.21.1
0.22.0
0.99.0
1.*
1.0.0
1.0.2
1.1.0
1.1.1
1.2.0
2.*
2.0.0
2.1.2
2.1.3
2.2.0
2.3.0
2.4.0
2.5.0
2.5.1
2.5.2
2.5.2-1
2.5.3
2.5.4
2.5.5
2.5.6
2.5.7
2.5.8
3.*
3.0.0
4.*
4.0.0
4.1.1
4.1.2
5.*
5.0.0
5.1.0
5.2.0
5.3.0
5.3.1
6.*
6.0.0~alpha0
6.0.0~alpha1
6.0.0~alpha2
6.0.0~beta2
6.0.0
6.1.0
6.1.1
6.2.1
6.2.2
ocaml-cohttp-0.*
ocaml-cohttp-0.9.1
ocaml-cohttp-0.9.2
ocaml-cohttp-0.9.3
ocaml-cohttp-0.9.4
ocaml-cohttp-0.9.5
ocaml-cohttp-0.9.7
ocaml-cohttp-0.9.10
v0.*
v0.9.11
v0.9.12
v0.9.13
v0.9.14
v0.9.15
v0.11.0
v0.11.1
v0.11.2
v0.12.0
v0.13.0
v0.14.0
v0.15.0
v0.15.1
v0.15.2
v0.16.0
v0.16.1
v0.17.0
v0.17.1
v0.17.2
v0.18.0
v0.18.2
v0.18.3
v0.19.0
v0.19.1
v0.19.2
v0.19.3
v0.20.0
v0.20.1
v0.21.0
v0.21.1
v0.22.0
v0.99.0
v1.*
v1.0.0
v1.0.1
v1.0.2
v1.1.0
v1.1.1
v1.2.0
v2.*
v2.1.0-cohttp-mirage
v2.1.1
v2.1.2
v2.1.3
v2.3.0
v2.4.0
v2.5.1
v2.5.2
v2.5.3
v2.5.4
v3.*
v3.0.0
v4.*
v4.0.0
v4.1.0
v5.*
v5.0.0
v6.*
v6.0.0
v6.0.0_alpha0
v6.0.0_alpha1
v6.0.0_beta1
v6.0.0_beta2
v6.1.0
v6.1.1
v6.2.0
v6.2.1
v6.2.2
v.*
v.0.15.1

Ecosystem specific

{
    "affected_bindings": [
        "Cohttp.Path.resolve_local_file",
        "Cohttp_async.Server.resolve_local_file",
        "Cohttp_lwt_unix.Server.resolve_file",
        "Cohttp_lwt.Make().resolve_local_file"
    ],
    "opam_constraint": "cohttp {< \"6.3.0\"}"
}

Database specific

source
"https://github.com/ocaml/security-advisories/blob/generated-osv/2026/OSEC-2026-16.json"