Elo脆弱性2件、任意コード実行のおそれ、修正版あり
npm版Eloに、細工した入力から任意のコードを実行されるおそれがある脆弱性が2件公表されました。Eloのソースを外部から受けて処理している組織は、1.0.1へ更新し、Ruby出力とJavaScript出力の使用有無を確認してください。
同じ発表の脆弱性 2 件
- CVE-2026-44266 重大 9.8
- CVE-2026-44267 重大 9.8
急ぎ度: 早めに
2件ともCVSS v3は9.8で、認証なしにネットワーク経由で悪用でき得る内容ですが、修正版1.0.1がすでに出ているため、外部入力を処理する環境から優先して更新すれば足ります。
関係があるか
Eloをルールエンジン、設定用DSL、フォームビルダーのDSLなどに組み込み、利用者や外部から受け取った文字列をコンパイルしている環境が対象です。CI/CDやDevOps用のホストで eloc や elo のコマンドを使っている場合も当てはまります。
| 製品 | 影響を受ける版 | 修正版 |
|---|---|---|
| @enspirit/elo(npm) | 1.0.1より前の版 | 1.0.1 |
確かめ方
- 1プロジェクトやCI用イメージで
npm ls @enspirit/eloを実行し、導入されている版が1.0.1より前でないかを見ます。ロックファイル(package-lock.jsonなど)も確認してください。 - 2Eloをライブラリとして呼び出している箇所を洗い出し、コンパイルする文字列に利用者の入力や外部システムのデータが混ざらないかを確かめます。
- 3出力先がRubyかJavaScriptかを確認します。Ruby出力は1件目、JavaScript出力は2件目の影響を受けます。
- 4npm以外の経路でEloを入れている場合は、ベンダーの告知で影響する版と修正版を確認してください。
何が起きたか
オープンソースの式言語Eloのコンパイラが、受け取った文字列をそのまま出力コードに書き込む作りになっていて、Ruby向けとJavaScript向けの出力にそれぞれ脆弱性がありました。細工されたEloのプログラムをコンパイルして実行すると、攻撃者が選んだコードが動きます。2件とも修正版は1.0.1です。
- CVE-2026-44266: Ruby出力で、文字列リテラルと部分型制約のラベルに含まれる
#{...}が実行時に評価され、任意のRubyコードやシェルコマンドが動く(CVSS v3は9.8) - CVE-2026-44267: JavaScript出力で、
.constructorなどのプロパティ参照が検査されずに出力され、実行環境(Node.jsやブラウザー)で任意のコードが動く(CVSS v3は9.8)
1件目の原因は、Rubyの二重引用符文字列に出力するとき # をエスケープしていなかったことです。さらに、部分型制約のラベルは、エスケープ処理をまったく通さずに出力されていました。同じEloのソースをJavaScript、Python、SQLに変換した場合、この1件目の問題は起きません。
2件目は、プロパティ名の検査がコンパイラのどの段階にもなく、JavaScript出力が名前をそのまま書き出すことで起きます。パーサーも、constructor のようなJavaScriptの組み込みプロパティ名を通常の識別子として受け入れます。「EloはDSLだから安全」という前提で使っていると、その前提が崩れます。
攻撃の流れ
-
1
細工した入力
攻撃者が、悪意のある文字列や式を含むEloのソースを、変換処理に渡せる経路へ送り込みます。
-
2
コンパイル
Eloのコンパイラが、入力中の文字列やプロパティ名を検査せずにRubyまたはJavaScriptのコードへ書き出します。
-
3
出力コードの実行
生成されたコードが実行されると、攻撃者が仕込んだ式が評価されます。
-
4
任意コード実行
実行プロセスの権限で、任意のコードやシェルコマンドが動きます。
どう悪用されるか
どちらも認証は要らず、利用者の操作も必要ありません。攻撃者は、細工したEloのソースをコンパイル処理まで届けられればよく、届け方はEloの使い方で変わります。
届く経路は、公開されたプレイグラウンド、CLI(eloc や elo)、ライブラリのAPI(defaultFormats.elo.parse())です。ライブラリの場合、Eloをルールエンジンや設定DSLとして組み込み、外部から受け取った式をコンパイルしている製品が主な標的になります。
2件の違いは出力先です。CVE-2026-44266はRuby出力を選び、生成されたRubyを実行したときに限って動きます。CVE-2026-44267はJavaScript出力を選び、生成されたJavaScriptを実行したときに動きます。
悪用に成功すると、実行したプロセスの権限で任意のコードが動きます。Ruby側ではシェルコマンドの実行にもつながります。CVSS上は、情報の漏えい、改ざん、サービス停止のすべてが最大の評価です。
今すぐやること
-
1
@enspirit/eloを1.0.1に更新する
package.jsonの指定を見直して1.0.1以降に上げ、ロックファイルを更新します。CI用のコンテナーイメージやグローバルにインストールしたCLIも忘れずに更新してください。
npm ls @enspirit/elo -
2
外部入力がEloに届く経路を洗い出す
利用者や外部システムの文字列がコンパイル処理に渡る箇所を一覧にし、更新の優先順位を付けます。公開サービスやマルチテナント環境に近いものから先に対応します。
-
3
Ruby出力とJavaScript出力の使用箇所を確認する
どちらの出力先を使っているかで、影響する脆弱性が変わります。使っていないほうの出力先でも、更新の対象は同じ1.0.1です。
-
4
更新前の実行環境に不審な跡がないか見る
外部入力を処理していた環境では、想定外のプロセス起動、外部への通信、見覚えのないファイルがないかを調べます。ベンダーの告知で、playground向けの案内や追加の注意点も確認してください。
すぐ更新できないとき
すぐに更新できない場合は、外部や利用者が入力した文字列をEloのコンパイラに渡さないようにしてください。信頼できない入力から生成したRubyやJavaScriptは実行しないことも同じく重要です。実行が避けられないときは、権限を絞ったコンテナーなど隔離環境で動かし、ネットワークとファイルへのアクセスを制限します。これらはつなぎの対策です。入力文字列の簡易的なフィルタリングだけでは、迂回される可能性があります。
背景
Eloは、ひとつの式の記述をRuby、JavaScript、Python、SQLなど複数の言語へ変換できる式言語です。ルールエンジン、設定ファイルのDSL、フォームの定義といった、画面や業務ルールの記述を共通化する用途が想定されています。ソースを各言語のコードに変換して実行する性質上、変換結果を安全に保つ責任がコンパイラ側にあります。
今回の2件は、ともにコンパイラの出力段階の不備です。入力中の文字列やプロパティ名が、出力先言語で特別な意味を持つ文字や名前かどうかを検査せず、そのまま書き出していました。とくにRuby出力は、同じソースをほかの言語に変換すると無害なため、出力先を切り替えたときに初めて問題が表に出る点が特徴です。移植性を保証するコンパイラなのに、出力先ごとに安全性が変わっていたことになります。
よくある質問
Q.PythonやSQLに出力している場合も更新は必要ですか。
Q.Eloを外部公開していなければ、急がなくてよいですか。
この記事は、取得元の公開情報をもとに、人が監修しながらAIを活用して執筆しています。執筆と監修は佐々木 航が担い、公開したあとも人が内容を確認しています。誤りに気づいたときは直し、記事の末尾に訂正の行を残します。対応を決める前に、下の原文と参照先も確認してください。
影響パッケージ
| 種類 | パッケージ | 影響を受ける版 | 修正版 |
|---|---|---|---|
| enspirit | elo | — | — |
| npm | @enspirit/elo |
1.0.1 未満 |
1.0.1 |
原文の説明 取得元が公開している説明をそのまま載せています (多くは英語)。
Elo is a purely functional expression language for no-code tools. Prior to 1.0.1, the Ruby backend in src/compilers/ruby.ts embeds attacker-controlled text in Ruby double-quoted strings without escaping #, so Ruby interpolation forms in the string-literal emitter or the labelled subtype-constraint branch become executable Ruby. The affected entry points include the /try playground with the Ruby target, bin/eloc -t ruby -x, and defaultFormats.elo.parse() followed by Ruby emission. A failing labelled subtype constraint evaluates its message, while an ordinary string literal is evaluated when the compiled Ruby runs, allowing Ruby code and shell command execution through backticks. JavaScript, Python, and SQL emission are not affected by this Ruby-specific path. This issue is fixed in version 1.0.1.
出典: CVE.org (CVE Program・cvelistV5) NVD GitHub Advisory
参照URL
- advisory github.com
- advisory github.com
- advisory nvd.nist.gov
- package github.com
- patch github.com
- patch github.com
- web github.com