OCaml Weekly News
Hello
Here is the latest OCaml Weekly News, for the week of August 18 to 25, 2026.
Table of Contents
- OSEC-2026-16: cohttp: path traversal
- Cascade: A Typed CSS Toolkit in OCaml
- YAMLx 0.5.0 + odds things about the project
- Opam repository package contributors should have a human behind them
- Cohttp 6.3.0 released (OSEC-2026-16)
- opam 2.6.0~alpha1
- Jane Street Libraries (base/core/async/etc) with 5.5
- OCaml running on a 1960s UNIVAC 1219B
- Old CWN
OSEC-2026-16: cohttp: path traversal
Hannes Mehnert announced
Dear everyone,
we just published a security advisory for cohttp - please find it below (and as usual at https://github.com/ocaml/security-advisories and https://osv.dev/list?q=&ecosystem=opam)
Best,
Hannes
id: OSEC-2026-16
modified: "2026-08-20T18:15:00Z"
published: "2026-08-20T18:15:00Z"
severity: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"
severity_score: "7.5 (High)"
affected: "cohttp" {< "6.3.0"}
events: [
[
git "https://github.com/mirage/ocaml-cohttp.git" [
[fixed "5f5a65ec3289c1cd8072bdf0ef22c181b4f11356"]
]
]
]
credits: [
[reporter "Sapphire Livingstone"]
[remediation_developer "Sapphire Livingstone"]
[remediation_developer "Anil Madhavapeddy"]
[remediation_reviewer "Anil Madhavapeddy"]
[remediation_reviewer "Michael Dales"]
[remediation_reviewer "Edwin Torok"]
[remediation_reviewer "Patrick Ferris"]
[coordinator "Hannes Mehnert"]
]
cwe: [ CWE-22 ]
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"
]
Path traversal in Cohttp.Path.resolve_local_file
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
- Aug 11th 2026: report to security@ocaml.org
- Aug 14th 2026: PR published on https://github.com/mirage/ocaml-cohttp/pull/1145
- Aug 20th 2026: fix released in v6.3.0 https://github.com/ocaml/opam-repository/pull/30528
Cascade: A Typed CSS Toolkit in OCaml
Continuing this thread, Thomas Gazagnaire announced
I have just released cascade 1.1.0 (which was just merged in opam) which improves the diff output quite a bit (especially on CSS sheets that user layers, containers, medias or other fancy structural elements) and adds something I wanted to rely on for a long time but for some reasons didn't think about adding earlier: a differential testing harness to test how a (headless) browser interpret a random CSS sheet on optimized vs. non-optimized mode. This allowed me to find quite a few issues (most of them as corner cases, but some were a bit embarassing) and explain the size of the CHANGELOG.
Happy to get any feedback on it, especially if the documentation is useful at all (I have tried without success to get some magic odoc runes to embed runnable CSS fragments in there, is this possible at all?)
YAMLx 0.5.0 + odds things about the project
Martin Jambon announced
I just released YAMLx 0.5.0 (release notes) which provides a few fixes and improvements since the original announcement in April. YAMLx is a pure-OCaml library implementing the complex YAML 1.1 and 1.2 specifications. It aims to provide a complete yet convenient user interface to manipulate data in this popular format.
Beyond the boring announcement, this is an opportunity for me to bring your attention (again?) to the unusual aspects of the YAMLx project. It is sacrilegious and experimental along 3 main axes:
AI use
- Most of the implementation is AI-generated (~10K lines).
- The interfaces are mostly human-crafted (~800 lines).
Authorship model
- The project has only one single traditional contributor.
- Contributions are encouraged in the form of bug reports and detailed feature requests.
- The project doesn't take external code contributions.
Funding
- The library is available for free under a strong copyleft license (AGPL).
- A one-time contribution ($500) gets your organization a perpetual commercial license.
- Past the funding threshold ($5,000), everyone will get a permissive license for free (ISC).
— I'm happy to go over the motivations for these choices. Just ask.
Opam repository package contributors should have a human behind them
Anil Madhavapeddy announced
Dear all,
I wanted to draw your attention to a new bit of opam-repository contribution guidance that we have just included.
14.Package contributors accounts should have a human behind them The review work by the maintainers ofopam-repositoryis carried out by humans, and we need to have a contact to respond to our feedback.Reasoning:
- A proposal for a new package can be submitted from bot accounts, but the PR should be tagged with a human contact so the opam-repo maintainers know who to talk to.
- Subsequent discussions regarding the PR should avoid excessive noise, such as large LLM-generated responses or automated triage logs, to avoid overloading the maintainers.
- Any machine generated comments on a package publication PR must be explicitly identified as such.
- When human reviewers ask questions or provide guidance, they must be met with human replies.
The motivation here is twofold: we have a small but growing number of submissions from projects that have bot-based release procedures. In several cases, this means we've had to dig out who the responsible person actually is.
And of course, there's more and more LLM spam out there waiting to spring on our poor human faces, but the submissions PRs have so far been largely considerate. Let's keep that going! Feedback welcome as always and the PR discussion here for those interested, and keep those opam package submissions coming :-)
Cohttp 6.3.0 released (OSEC-2026-16)
Anil Madhavapeddy announced
Dear all,
cohttp 6.3.0 is released onto opam-repository with some important security fixes (OSEC-2026-16):
- cohttp:
Cohttp.Path.resolve_local_fileno longer escapes the docroot when given percent-encoded traversal sequences such as..%2f..%2f. The URI path is percent-decoded exactly once before.and..segments are removed. (#1145 @avsm and Sapphire Livingstone, review by @mdales @edwintorok @patricoferris) - cohttp:
Cohttp.Path.resolve_local_filecollapses empty path segments and drops a trailing slash. A request for/dir//sub/now resolves todocroot/dir/subinstead ofdocroot/dir//sub/. (#1145 @avsm) cohttp: Add
Cohttp.Path.normalise, which converts a request URI into a relative path that cannot ascend above its root. Servers that make access control decisions on path segments must apply it toRequest.uribefore inspecting them, asRequest.uridoes not normalise absolute-form or percent-encoded targets. (#1145 @avsm)let callback _conn req _body = let uri = Cohttp.Request.uri req in match String.split_on_char '/' (Cohttp.Path.normalise uri) with | "admin" :: _ when not (authorised req) -> Server.respond_not_found () | _ -> let fname = Cohttp.Path.resolve_local_file ~docroot ~uri in Server.respond_file ~fname ()Normalisation is not applied by default, as existing code may depend on the present semantics, which are safe when not combined with local file resolution.
- cohttp-mirage: The static file server normalises the request path of every
request, including directory requests, before looking it up in the mirage-kv
store. Keys are now percent-decoded, so
/my%20file.txtretrieves the keymy file.txtrather thanmy%20file.txt(#1145 @avsm, review by @mdales @edwintorok) - cohttp-mirage: The
request_fncallback receives the request URI unchanged. A request that falls back to an index page previously received a URI rewritten to that page. (#1145 @avsm) - cohttp: do not add
Transfer-Encoding~/~Content-Lengthframing headers to responses that cannot have a body (1xx, 204 and 304). This fixes WebSocket handshakes. (@mefyl @avsm, #1141) - http: add
Status.body_allowed, the response-status counterpart to the existingMethod.body_allowed, for users constructing responses by hand (#1141)
Please upgrade as soon as possible, and note the new normalise function for your own HTTP path splitting needs.
Thank you to everyone who helped with handling the security issue, and especially Sapphire Livingstone for the discovery, report and guidance with the fix:
- 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
opam 2.6.0~alpha1
Continuing this thread, Kate announced
Hi everyone,
We are happy to announce the release of opam 2.6.0~beta1.
This version is a beta, we invite users to test it to spot previously unnoticed bugs as we head towards the stable release.
Main changes compared to 2.6.0~alpha1
- :recycling_symbol:
opam init --reinit(command typically called after upgrading from an older opam version) got improved. It now stops asking to retry the command when upgrading from a 2.1 opam root, and regenerates switches metadata to allow tools that use the opam library to load the switch informations without modifying the opam root (#7057, #7066) - :houses: When
--safeis given, opam used to reset debug-level to 0. This is no longer the case. Consider updating your scripts accordingly. (#7000) - :shuffle_tracks_button: opam now disable git gc/maintenance on repositories it maintains. This is because git spawns maintenance tasks in the background which creates/removes/modifies files and unaware opam processes can sometimes break on a race-condition when handling such a git repository (#7031)
:open_book: You can read our blog post for more information about these changes and more, and for even more details you can take a look at the release note or the changelog.
Try it!
The upgrade instructions are unchanged:
For Unix systems
bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.6.0~beta1"
or from PowerShell for Windows systems
Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.6.0~beta1"
Please report any issues to the bug-tracker.
Happy hacking, <> <> The opam team <> <> :camel:
Jane Street Libraries (base/core/async/etc) with 5.5
Stefan Muenzel announced
(Note: much of the linked repos are modified with the the help of LLMs, so please do check the diff to the upstream version before installing. Most diffs are very small. Also, this release is not affiliated with Jane Street)
Since the current version of the Jane Street public release libraries are targeting either older version of the compiler, or OxCaml, I've made a version of the jane street opam repository that targets 5.5.
Almost all ~300 libraries are available (or at least build), with the exception of some heavy oxcaml users, such as skyline. Versions available are v0.18_preview.130.100+614 and v0.18_preview.130.106+341.
The opam repository is available at https://github.com/public-release-reloaded/opam-repository, and the repo used to generate this is at https://github.com/public-release-reloaded-engineering/public-release-reloaded
Note that you need ppxlib > 0.38.0, due to https://github.com/ocaml-ppx/ppxlib/pull/644
I believe things should mostly work, but please do comment about any issues that you have.
OCaml running on a 1960s UNIVAC 1219B
Nathan Farlow announced
Hi!
I've been meaning to post a recent-ish project of mine where I ran OCaml (and much more) on a 1960s UNIVAC 1219B! The demo I chose to run was a sudoku solver. In short, this was done by compiling OCaml to C, C to RISC-V, and then emulating RISC-V on the UNIVAC.
Full UNIVAC toolchain: Writeup, and source. Please see the my comment below for the other links! I'm unable to post more than two links in a post.
I also ran an OCaml program submitted by a friend that computed factors of numbers. At one point we thought the program crashed, but we were delighted when the program resumed ~5 minutes later. Turns out garbage collecting is slow on this machine :slight_smile:
Oh, and it works with OxCaml too!
Enjoy! Below are some pictures. (Disregard the earlier output, that was a run of ELIZA :slight_smile:)
Editor note: I’m inlining the links that were in the subsequent messages.
OCaml to C: Writeup, and source
Sudoku solver source: OCaml, and compiled to C
Old CWN
If you happen to miss a CWN, you can send me a message and I'll mail it to you, or go take a look at the archive or the RSS feed of the archives.
If you also wish to receive it every week by mail, you may subscribe to the caml-list.