Every CVESearch/Get API key

OSEC-2026-28

Unauthenticated arbitrary file read via path traversal in `/conferences/ocaml/**`

7.5 High

OSEC-2026-28 is a high vulnerability (CVSS 7.5), published November 6, 2026. No source lists public exploit code. No source names a fixed version.

What does this mean?
Severity
7.5 HighCVSS 3.1, OSV
Exploit chance
UnscoredNo EPSS score yet
Exploitation
None knownNot on CISA’s or ENISA’s lists
Fixed in
No fix listedNo source names one

Description

GET /conferences/ocaml/<path> on ocaml.org concatenates the raw request target onto OCAMLORG_V2_PATH (/v2) and serves it with Dream.from_filesystem, bypassing the path validation that Dream.static performs. An unauthenticated request containing .. segments escapes /v2 and reads arbitrary files as the server process, which runs as root in the container.

Please note that the live deployment of https://ocaml.org is in a dedicated Docker container which does not contain any secrets. Thus the vulnerability is in the ocaml.org source code, but there has been no impact for the live deployment.

Affected code

src/ocamlorg_web/lib/handler.ml:1544 (commit ocaml/ocaml.org@31249f2d69fcb243284d3a6a2b91c0a4963f25b5):

let v2_asset req =
  let</>? path =
    try Some (Config.v2_path ^ Dream.target req) with _ -> None
  in
  let</>? () = if Sys.file_exists path then Some () else None in
  Filename.(Dream.from_filesystem (dirname path) (basename path) req)

The route is public (src/ocamlorg_web/lib/router.ml:186):

Dream.get "/conferences/ocaml/**" Handler.v2_asset;

Config.v2_path is OCAMLORG_V2_PATH, set to /v2 in the production image (Dockerfile:68). Dream.target is the request target as received; nothing rejects . or .. components.

Timeline

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
None
Availability
None

What each source reports

OSV Score used7.5

Unauthenticated arbitrary file read via path traversal in `/conferences/ocaml/**`

GET /conferences/ocaml/<path> on ocaml.org concatenates the raw request target onto OCAMLORG_V2_PATH (/v2) and serves it with Dream.from_filesystem, bypassing the path validation that Dream.static performs. An unauthenticated request containing .. segments escapes /v2 and reads arbitrary files as the server process, which runs as root in the container.

Please note that the live deployment of https://ocaml.org is in a dedicated Docker container which does not contain any secrets. Thus the vulnerability is in the ocaml.org source code, but there has been no impact for the live deployment.

Affected code

src/ocamlorg_web/lib/handler.ml:1544 (commit ocaml/ocaml.org@31249f2d69fcb243284d3a6a2b91c0a4963f25b5):

let v2_asset req =
  let</>? path =
    try Some (Config.v2_path ^ Dream.target req) with _ -> None
  in
  let</>? () = if Sys.file_exists path then Some () else None in
  Filename.(Dream.from_filesystem (dirname path) (basename path) req)

The route is public (src/ocamlorg_web/lib/router.ml:186):

Dream.get "/conferences/ocaml/**" Handler.v2_asset;

Config.v2_path is OCAMLORG_V2_PATH, set to /v2 in the production image (Dockerfile:68). Dream.target is the request target as received; nothing rejects . or .. components.

Timeline

Record
OSEC-2026-28
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Updated
2026-11-06

History

History
RecordedChangedSources
first indexedOSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

MoveEnter Open