
閉ループ型の脆弱性修復:検出 → エクスプロイトの再現 → パッチの生成 → プルーフハーネスによる検証。実例:Langflow CVE-2026-33017
閉ループ型の脆弱性修復パイプライン:検出 → エクスプロイトの再現 → パッチの生成 → プルーフハーネスに対するパッチの検証 — これらすべてを経て初めて修正が信頼される。
「AIがあなたのCVEを修正する」というデモのほとんどは、パッチの生成で止まってしまいます。kavach-loopは、脆弱なソフトウェアの実際に動作しているインスタンスに対して次の2点を証明するまで、パッチを信頼しません:(1) 元のエクスプロイトがもはや機能しないこと、(2) アプリケーションが依然として正常に動作すること。実例として、実際の重大なCVEを取り上げています。
⚠️ 適用範囲と安全性: ネットワークに触れるすべてのモジュールはローカルホスト(
127.0.0.1/::1)にハードロックされており、それ以外のターゲットを拒否します。エクスプロイトコードは、自分で実行する使い捨てコンテナに対してパッチが機能することを証明するために存在するものであり、何かを攻撃するためのものではありません。必ず同梱のターゲットに対してのみ実行してください。
Langflow ≤ 1.8.2 における未認証のリモートコード実行 — GHSA-vwmf-pq79-vjvx / NVD。POST /api/v1/build_public_tmp/{flow_id}/flow は認証なしでパブリックフローをビルドします。攻撃者が指定したノードの code は、ルートハンドラからシンクに至る6ホップの呼び出しチェーンを通じて、サンドボックスなしで exec() に到達します。
flowchart LR
T["exploit_repro/<br/>disposable Langflow 1.8.2<br/>container (localhost only)"]
D["detection/<br/>Semgrep rule over<br/>live-extracted source"]
E["exploit_repro/exploit.py<br/>PoC: confirm RCE is real"]
P["patch_gen/<br/>LLM unified diff,<br/>applied to a real copy"]
V["proof_harness/verify.py<br/>exploit blocked? + app<br/>still works? → one verdict"]
T --> D --> E --> P --> V
V -->|fused confidence score| OUT["trusted / rejected"]
| ステージ | モジュール | 実際に何をするか |
|---|---|---|
| Detect | detection/detect.py + rules/unauthenticated-exec-sink.yaml | ターゲットコンテナからライブで取得したソースに対して実際のSemgrepスキャンを実行します。このルールは、確実に検出可能な前提条件(認証されていないルートが攻撃者制御の入力を下流の呼び出しに転送する)を正直にフラグ付けするものであり、6ホップ全体のテイント解析ではありません。そしてその旨をconfidence: LOWで明示しているため、すべてのヒットは依然として確認が必要です。 |
| Reproduce | exploit_repro/exploit.py | RCEが実際に発火することを確認するlocalhost限定のPoCです。これにより、静的解析の推測ではなく実際のバグを修正していることが保証されます。 |
| Patch | patch_gen/generate.py | 実行中のコンテナから脆弱な関数の実際の現在のソースを取得し、1〜2件の参考修正パターンを取得し、LLMにunified diffを要求したうえで、それを2つ目の使い捨てコンテナに適用して再起動し、パッチ適用済みコードを再読み込みさせます。 |
| Verify | proof_harness/verify.py + test_functionality.py | 2つのチェックを1つの判定に統合します。PoCが今度は失敗すること、かつLangflowの通常の認証済みREST API(health、version、whoami、フローCRUD)が引き続きパスすることの両方が必要です。アプリを骨抜きにしてエクスプロイトを阻止するパッチは却下されます。 |
この正直さこそが要点です。検出ルールは、何を証明し何を証明しないのかを正確に文書化しており、検証器はエクスプロイトが止まったというだけではパッチを良好とは判定しません。
pip install -r requirements.txt # requests, pytest, openai, semgrep
export OPENAI_API_KEY=... # for patch_gen
cd exploit_repro/langflow-cve-2026-33017
docker compose up -d # vulnerable target on 127.0.0.1:7860
curl -s http://127.0.0.1:7860/health
cd ../..
python detection/detect.py # static-analysis finding
python exploit_repro/exploit.py # confirm the RCE (localhost only)
python patch_gen/generate.py # generate + apply + verify a patch
pytest proof_harness/ # functionality smoke tests
停止してワイプ: docker compose down -v。
個々のステージ(検出、エクスプロイト再現、パッチ生成、プルーフハーネス)は実装済みで、実際のターゲットに対して実行されます。main.py は薄いオーケストレーションの骨組みです — 現時点ではステージは上記のように直接駆動されています。それらを単一の main() 呼び出しに配線することが次のステップです。
Kavach(कवच)はサンスクリット語で「鎧」を意味します。このループこそが鎧です。攻撃され、耐えられることが示されるまで、何も出荷されません。