OSEC-2026-28
Unauthenticated arbitrary file read via path traversal in `/conferences/ocaml/**`
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.
- 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
- 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
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 used 7.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
- 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
- Record
OSEC-2026-28- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-06
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.