OSEC-2026-28: Unauthenticated arbitrary file read via path traversal in `/conferences/ocaml/**`
GET /conferences/ocaml/<path> on ocaml.org concatenates the raw request target onto OCAMLORGV2PATH (/v2) and serves it with Dream.fromfilesystem, 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/ocamlorgweb/lib/handler.ml:1544 (commit ocaml/ocaml.org@31249f2d69fcb243284d3a6a2b91c0a4963f25b5):
ocaml let v2asset req = let</>? path = try Some (Config.v2path ^ Dream.target req) with -> None in let</>? () = if Sys.fileexists path then Some () else None in Filename.(Dream.fromfilesystem (dirname path) (basename path) req)
The route is public (src/ocamlorgweb/lib/router.ml:186):
ocaml Dream.get "/conferences/ocaml/" Handler.v2asset;
Config.v2path is OCAMLORGV2PATH, set to /v2 in the production image (Dockerfile:68). Dream.target is the request target as received; nothing rejects . or .. components.
Timeline
- 2026-10-31 report via https://github.com/ocaml/security-advisories - 2026-11-02 fixed via https://github.com/ocaml/ocaml.org/pull/3942 and deployed ocaml.org
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
ocaml/ocaml.orgto a version that resolves this vulnerability.Patch ocaml/ocaml.org/pull/3942