OCaml Weekly News

先週号 上へ 次週号

こんにちは

2026年8月18日から25日までの週の OCaml Weekly News をお届けします。

Table of Contents

OSEC-2026-16: cohttp: パストラバーサル

Hannes Mehnert が発表しました

皆さんへ、

cohttp に関するセキュリティアドバイザリを公開しました。以下および通常通り https://github.com/ocaml/security-advisories および https://osv.dev/list?q=&ecosystem=opam でご確認ください。

よろしくお願いします。

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"
]

Cohttp.Path.resolve_local_file におけるパストラバーサル

問題は、この関数が URI パスをパーセントデコードする前に正規化している点にあります:

let resolve_local_file ~docroot ~uri =

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

   ...

%2f は Uri.resolve の後にデコードされるため、エンコードされたセパレータがドットセグメントの正規化を生き残ってしまいます。例えば、以下のようなリクエストパス:

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

は単一のエンコードされたセグメントとして正規化された後、以下のようにデコードされます:

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

タイムライン

Cascade: OCaml による型付き CSS ツールキット

このスレッドを引き継いで、Thomas Gazagnaire が発表しました

cascade 1.1.0 をリリースしました(opam にマージ済み)。今回のリリースでは diff 出力が大幅に改善されました(特にレイヤー、コンテナ、メディア、その他のファンシーな構造要素を使用した CSS シートに対して)。また、長い間利用したいと思っていたにもかかわらず、なぜか追加しようと思わなかった機能も追加しました:ランダムな CSS シートを最適化モードと非最適化モードで(ヘッドレス)ブラウザがどのように解釈するかをテストするための差分テストハーネスです。これにより、いくつかの問題(ほとんどはコーナーケースでしたが、いくつかは少々恥ずかしいものでした)を発見でき、CHANGELOG のサイズの説明がつきます。

フィードバックをいただければ嬉しいです。特に ドキュメント が役に立つかどうか教えてください(実行可能な CSS フラグメントをそこに埋め込むための魔法の odoc ルーンを取得しようとして成功しませんでしたが、これは可能なのでしょうか?)

YAMLx 0.5.0 + プロジェクトにまつわる変わった話

Martin Jambon が発表しました

YAMLx 0.5.0(リリースノート)をリリースしました。4月の最初のアナウンス以降のいくつかの修正と改善が含まれています。YAMLx は、複雑な YAML 1.1 および 1.2 仕様を実装した pure-OCaml ライブラリです。この人気のあるフォーマットでデータを操作するための、完全でありながら便利なユーザーインターフェースの提供を目指しています。

退屈なアナウンスはさておき、YAMLx プロジェクトの異色な側面に(再び?)注目していただく良い機会です。このプロジェクトは3つの主要な軸において異端的かつ実験的です:

AI の活用

  • 実装のほとんどは AI によって生成されています(約1万行)。
  • インターフェースはほぼ人間が設計しています(約800行)。

著作権モデル

  • プロジェクトには従来の意味での貢献者が一人だけです。
  • バグ報告や詳細な機能リクエストという形での貢献を歓迎します。
  • 外部からのコード貢献は受け付けていません。

資金調達

  • ライブラリは強いコピーレフトライセンス(AGPL)の下で無償で利用可能です。
  • 一度限りの貢献($500)により、組織は永続的な商用ライセンスを取得できます。
  • 資金調達の閾値($5,000)を超えた場合、誰もが無償でパーミッシブライセンス(ISC)を取得できます。

— これらの選択の動機については喜んでお答えします。お気軽にどうぞ。

opam リポジトリのパッケージ貢献者は人間が背後にいるべき

Anil Madhavapeddy が発表しました

皆さんへ、

新たに追加した opam-repository への貢献ガイダンス についてお知らせしたいと思います。

14. パッケージ貢献者のアカウントには人間が背後にいるべき opam-repository のメンテナーによるレビュー作業は人間によって行われており、フィードバックに応答できる連絡先が必要です。

理由:

  • 新しいパッケージの提案はボットアカウントから送信されても構いませんが、PR には人間の連絡先をタグ付けして、opam-repo メンテナーが誰に話しかければよいかわかるようにする必要があります。
  • パッケージ公開 PR に関するその後の議論では、メンテナーに過度な負担をかけないよう、大量の LLM 生成レスポンスや自動トリアージログなどの過剰なノイズを避ける必要があります。
  • パッケージ公開 PR への機械生成コメントはすべて明示的にそのように識別されなければなりません。
  • 人間のレビュアーが質問をしたりガイダンスを提供したりした場合、人間による返答が必要です。

この動機は二つあります:ボットベースのリリース手順を持つプロジェクトからの投稿が少しずつ増えており、いくつかのケースでは責任者が実際に誰であるかを掘り起こす必要がありました。

そして当然ながら、私たちの哀れな人間の顔に降りかかってくる LLM スパムが増えてきていますが、投稿 PR はこれまでのところ概ね配慮あるものでした。この流れを維持していきましょう!フィードバックはいつでも歓迎です。興味のある方は PR のディスカッションはこちら をご覧いただき、引き続き opam パッケージの投稿をよろしくお願いします :-)

Cohttp 6.3.0 リリース (OSEC-2026-16)

Anil Madhavapeddy が発表しました

皆さんへ、

cohttp 6.3.0 が重要なセキュリティ修正(OSEC-2026-16)とともに opam-repository にリリースされました:

  • cohttp: Cohttp.Path.resolve_local_file は、..%2f..%2f のようなパーセントエンコードされたトラバーサルシーケンスが与えられた場合に docroot を脱出しなくなりました。URI パスは . および .. セグメントが除去される前に正確に一度だけパーセントデコードされます。 (#1145 @avsm および Sapphire Livingstone、@mdales @edwintorok @patricoferris によるレビュー)
  • cohttp: Cohttp.Path.resolve_local_file は空のパスセグメントを折り畳み、末尾のスラッシュを削除します。/dir//sub/ へのリクエストは docroot/dir//sub/ ではなく docroot/dir/sub に解決されるようになりました。(#1145 @avsm)
  • cohttp: Cohttp.Path.normalise を追加しました。これはリクエスト URI をルートより上に昇ることができない相対パスに変換します。パスセグメントに対してアクセス制御の判断を行うサーバーは、それらを検査する前に Request.uri に適用する必要があります。Request.uri は絶対形式またはパーセントエンコードされたターゲットを正規化しないためです。(#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 ()
    

    正規化はデフォルトでは適用されません。既存のコードが現在のセマンティクスに依存している可能性があるためです。現在のセマンティクスはローカルファイル解決と組み合わせなければ安全です。

  • cohttp-mirage: 静的ファイルサーバーは、ディレクトリリクエストを含むすべてのリクエストのリクエストパスを、mirage-kv ストアで検索する前に正規化します。キーはパーセントデコードされるようになったため、/my%20file.txt は my%20file.txt ではなく my file.txt キーを取得します。(#1145 @avsm、@mdales @edwintorok によるレビュー)
  • cohttp-mirage: request_fn コールバックはリクエスト URI を変更せずに受け取ります。インデックスページにフォールバックするリクエストは以前、そのページに書き換えられた URI を受け取っていました。(#1145 @avsm)
  • cohttp: ボディを持てないレスポンス(1xx、204、304)に Transfer-Encoding~/~Content-Length フレーミングヘッダーを追加しなくなりました。これにより WebSocket ハンドシェイクが修正されます。(@mefyl @avsm、#1141)
  • http: レスポンスを手動で構築するユーザー向けに、既存の Method.body_allowed に対応するレスポンスステータス版として Status.body_allowed を追加しました。(#1141)

できるだけ早くアップグレードしてください。また、独自の HTTP パス分割のニーズに対応する新しい normalise 関数もご注目ください。

セキュリティ問題の対応にご協力いただいた皆さん、特に発見・報告・修正のガイダンスをしてくださった Sapphire Livingstone に感謝します:

  • 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

このスレッドを引き継いで、Kate が発表しました

皆さんへ、

opam 2.6.0~beta1 のリリースをお知らせできることを嬉しく思います。

このバージョンはベータ版です。安定版リリースに向けて、これまで気づかれなかったバグを発見するためにユーザーのテストをお願いします。

2.6.0~alpha1 からの主な変更点

  • :recycling_symbol: opam init --reinit(古い opam バージョンからアップグレード後に通常呼び出されるコマンド)が改善されました。2.1 の opam ルートからアップグレードする際にコマンドの再試行を求めるメッセージが表示されなくなり、opam ルートを変更せずに opam ライブラリを使用するツールがスイッチ情報を読み込めるようにスイッチのメタデータを再生成するようになりました。(#7057、#7066)
  • :houses: --safe が指定された場合、opam はデバッグレベルを 0 にリセットしていましたが、これはもはや行われません。スクリプトを適宜更新することをご検討ください。(#7000)
  • :shuffle_tracks_button: opam は管理しているリポジトリで git gc/maintenance を無効にするようになりました。これは、git がバックグラウンドでメンテナンスタスクを起動し、ファイルの作成・削除・変更を行うため、それを知らない opam プロセスがそのような git リポジトリを処理する際にレースコンディションで失敗することがあるためです。(#7031)

:open_book: これらの変更の詳細については ブログ記事 をご覧ください。さらに詳しくは リリースノート または changelog をご参照ください。

試してみてください!

アップグレード手順は変わっていません:

Unix システムの場合

bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.6.0~beta1"

または Windows システムの PowerShell から

Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.6.0~beta1"

問題が発生した場合は バグトラッカー にご報告ください。

Happy hacking, <> <> The opam team <> <> :camel:

Jane Street ライブラリ (base/core/async/etc) と 5.5 の対応

Stefan Muenzel が発表しました

(注:リンク先のリポジトリの多くは LLM の助けを借りて修正されています。インストール前にアップストリームバージョンとの差分を確認してください。ほとんどの差分は非常に小さいです。また、このリリースは Jane Street とは関係ありません)

現在の Jane Street 公開リリースライブラリは古いバージョンのコンパイラか OxCaml をターゲットにしているため、5.5 をターゲットにした Jane Street opam リポジトリのバージョンを作成しました。

約 300 のライブラリのほぼすべてが利用可能(または少なくともビルド可能)です。ただし、skyline などの OxCaml ヘビーユーザーは除きます。利用可能なバージョンは v0.18_preview.130.100+614 と v0.18_preview.130.106+341 です。

opam リポジトリは https://github.com/public-release-reloaded/opam-repository にあり、これを生成するために使用したリポジトリは https://github.com/public-release-reloaded-engineering/public-release-reloaded にあります。

https://github.com/ocaml-ppx/ppxlib/pull/644 のため、ppxlib > 0.38.0 が必要な点にご注意ください。

概ねうまく動くと思いますが、何か問題があればコメントしてください。

1960年代の UNIVAC 1219B 上で動く OCaml

Nathan Farlow が発表しました

こんにちは!

最近のプロジェクトを投稿しようと思っていました。1960年代の UNIVAC 1219B 上で OCaml(そしてそれ以上のもの)を動かしました!選んだデモは数独ソルバーです。簡単に言うと、OCaml を C にコンパイルし、C を RISC-V にコンパイルして、UNIVAC 上で RISC-V をエミュレートすることで実現しました。

UNIVAC ツールチェーン全体:解説記事、および ソースコード。その他のリンクについては以下のコメントをご覧ください!1つの投稿に2つ以上のリンクを載せることができないためです。

友人が提出した数値の因数を計算する OCaml プログラムも動かしました。ある時点でプログラムがクラッシュしたと思いましたが、約5分後にプログラムが再開したときは大喜びしました。このマシンではガベージコレクションが遅いことがわかりました :slight_smile:

OxCaml でも動作します!

お楽しみください!以下にいくつかの写真を載せます(以前の出力は無視してください、ELIZA を実行した際のものです :slight_smile:)

f77dc661631e09e5aab6f5024997dc3556553524_2_750x1000.jpeg

571ce6aa512595b1f5cd130cd2b181ddcb3b6401_2_1332x1000.jpeg

編集者注:以降のメッセージにあったリンクをここに埋め込みます。

OCaml から C へ:解説記事、および ソースコード

数独ソルバーのソースコード:OCaml、および C にコンパイルされたもの

過去の CWN

CWN を見逃した場合は、メッセージを送っていただければメールでお送りします。また、アーカイブやRSS フィードもご覧いただけます。

毎週メールで受け取りたい場合は、caml-list を購読してください。