2026年8月22日のAikido Intel日次に載ったCritical/High 6件(agno、cap-primitives、Spring×4)を入口に、Path Traversal・XSS・Code Injection・Deserializationという古典的な「型」の40年史をたどり、被害の大きさは1件のCVSSでは決まらない「合わせ技」の見方を解説する。
2026年8月22日、Aikido Intelの日次レポートに新着として流れた脆弱性は29件。そのうちCritical/Highは6件だった(CVE自体の公開日は4月〜8月20日で、8月22日は日次に載った日である)。
| パッケージ | 言語 | ID | 深刻度 | 型(日本語) | 修正版 |
|---|---|---|---|---|---|
| agno | Python | CVE-2026-35002 | Critical (98) | Code Injection(文字列のはずの入力を命令として実行してしまう) | 2.3.24 |
| cap-primitives | Rust | GHSA-hp8f-xmx4-4qrg | Critical (90) | Path Traversal(本来触れないフォルダの外へ抜ける) | 3.4.6 / 4.0.3 |
| spring-integration-core | Java | CVE-2026-59324 | High (82) | Information Disclosure(他人の情報が見える) | 5.5.22 / 6.4.13 / 6.5.11 ほか |
| spring-security-oauth2-authorization-server | Java | CVE-2026-59316 | High (82) | XSS(他人のブラウザで攻撃者のコードを動かす) | 1.4.12 / 1.5.9 |
| spring-graphql | Java | CVE-2026-59285 | High (81) | Deserialization(受け取ったデータをオブジェクトに戻す処理の悪用) | 2.0.5 |
| spring-integration-jdbc | Java | CVE-2026-59307 | High (80) | Deserialization(同上) | 6.4.13 / 6.5.11 / 7.0.6 ほか |
一覧を眺めて気づくのは、「型」の欄に新しい言葉がひとつもないことだ。Path Traversal、XSS、Code Injection、Deserialization。どれも20年から40年、セキュリティの世界にいる古典である。
もちろん、新しい種類の脆弱性や攻撃面も生まれている。この記事が言いたいのはそこではない。古典的な型が、新しい技術の層にも繰り返し現れる、ということだ。6件をきっかけに「型」の歴史をたどり、最後に、1件ずつの深刻度だけを見ていると見落とす「合わせ技」の話をする。
「../」を使って許されていないディレクトリへ抜ける手口は、1990年代のCGIスクリプト時代にはすでに定番だった。世界的に知られるきっかけは2001年のNimdaワームで、IISのUnicodeディレクトリトラバーサルを踏み台に、数時間で世界中に広がった。
以来25年、CWE Top 25の常連である。一向に消えない理由は単純で、これは「バグ」というより「論理の穴」だからだ。言語やコンパイラでは防げない。ファイルパスという文字列をどう解釈するか、という設計判断の問題である。
今回の cap-primitives は、その皮肉を象徴している。このクレート(Rustでいうライブラリ/パッケージ)は、cap-std というRustのライブラリ群の土台で、目的はひとつ。「プログラムに、最初に渡したフォルダの中しか触らせない」ことだ。たとえば /data フォルダを渡したら、どんなパスを指定されても /data の外には出られない。そういう「鍵のかかった箱」を作るための部品である。
その箱に、外へ出られる穴が見つかった。手口そのものは昔の単純な「../」ではなく、末尾のスラッシュとシンボリックリンクの扱いをめぐる挙動の組み合わせで、アドバイザリ自身が Path Traversal(CWE-22)と Link Following(CWE-59)の両方に分類し、閉じ込めを完全に破れるとしている。だが「本来閉じ込めたディレクトリの外へ出られる」という型は同じだ。Rustという言語はメモリ破壊(古い型の筆頭)を仕組みごと消したが、「このパスは箱の外か内か」という判断の誤りまでは言語では消せない。守る側が積んだ最前線の層に、古典がそのまま再出現している。
Cross-Site Scriptingという名前が付いたのは2000年、Microsoftの命名による。2005年、MySpaceで「Samyワーム」が20時間で100万人超に広がり、XSSが「ブラウザの中で自己増殖できる」ことを世界に示した。OWASP Top 10でも長く主要項目として扱われ、2021年版ではInjectionに統合された。
それでも現場では、XSSは「他の脆弱性より軽い」と扱われがちだ。サーバーを乗っ取るわけではない、という理屈である。
今回の spring-security-oauth2-authorization-server は、その感覚が最も通用しない場所にXSSが出た例だ。内容は、既定の同意画面(Default Consent Page)が攻撃者の値をエスケープせずに表示するというもので、独自の同意画面を使っていれば影響しない。しかし認可サーバーとは、ユーザーが「このアプリにどの権限を与えるか」を判断する場所である。そこで攻撃者のスクリプトが動く。XSSは同じでも、出る場所によって意味が変わる。
「データのつもりで渡した文字列が、命令として実行される」。この構図は1998年、rain.forest.puppyがPhrack誌でSQLインジェクションを紹介したときから変わっていない。PHPの eval() に外部入力を渡す事故が量産され、2015年にはPortSwiggerのJames Kettleがテンプレートインジェクション(SSTI)として体系化した。
今回の agno はAIエージェントのフレームワークで、スコアは98、今日の最高値だ。中身は意外なほど古典的で、FunctionCall(モデルが呼び出す関数)の引数にある field_type という値がそのまま Python の eval() に渡されていた。攻撃者がこの値に手を出せれば、任意のPythonコードが動く。分類もEval Injection(CWE-95)である。
つまり「AIだから新しい種類の脆弱性になった」のではない。モデルが関与するFunctionCallという新しい入口から、昔ながらのEval Injectionに到達した。AIエージェントという新しい実行基盤の中にも、結局 eval() という古典的な危険が残っていた、ということだ。
デシリアライズとは、ファイルや通信で受け取ったデータを、プログラムの中で使えるオブジェクトに組み立て直す処理のことだ。問題は、Javaではこの「組み立て直し」の途中で、受け取ったデータの指示どおりにプログラム側のコードが動いてしまう場合があること。攻撃者が細工したデータを送れば、組み立てているつもりで攻撃者の命令を実行している、という状態になる。
これが広く知られたのは2015年。1月の研究発表(Frohoff と Lawrence の「Marshalling Pickles」)で道筋が示され、11月に「どこにでも入っている部品(Apache Commons Collections)を使えば実際に動く」ことが公開されると、WebLogic、JBoss、Jenkinsなど主要なJava製品が軒並み該当した。
そして2026年8月、Springで2件。spring-graphql は条件が重なれば任意コード実行に至り、spring-integration-jdbc は攻撃者がDBのメッセージ格納列(INT_MESSAGE.MESSAGE_CONTENT)へ細工したデータを書き込めることが前提だが、そこから任意コード実行に至る。前提条件はあるにせよ、11年経っても、Javaエコシステムはこの型と決着がついていない。
| 型 | 初出・象徴的事件 | 2026年8月22日の出先 |
|---|---|---|
| Path Traversal | 1990年代CGI、Nimda (2001) | Rustのサンドボックス基盤 |
| XSS | 命名2000年、Samy (2005) | OAuth2認可サーバーの同意画面 |
| Code Injection | SQLi (1998)、SSTI (2015) | AIエージェント基盤の eval() |
| Deserialization | Marshalling Pickles (2015) | Spring GraphQL / Integration JDBC |
CGI → Webフレームワーク → サンドボックス基盤 → AIエージェント。守る側が層を積むたびに、その新しい層に古典が再出現している。
この表にない古典もまだ現役である。SQLインジェクションは2008年のHeartland(カード情報1億件超)、2011年のSony Picturesと被害が続き、今も毎週のように新しいCVEが出る。メモリ破壊は1988年のMorrisワーム、1996年の「Smashing the Stack」、2014年のHeartbleedと40年の歴史があり、Rustはこれを消すために生まれた。SSRF(サーバーに代わりに取りに行かせる型)はクラウド以前は地味だったが、2019年のCapital One以降は花形になった。「置き場所で格が変わる」典型である。
ここからが本題かもしれない。
脆弱性の深刻度は1件ごとに付く。CVSSも、Aikidoのスコアも、1件を評価する数字だ。足し算も掛け算もできない。ところが歴史上の大きな侵入は、ほぼ例外なく複数の要素をつないで起きている。
今日の6件に当てはめるなら、公開情報から「この2件は直接つながる」と言える組み合わせはない。だからこそ問うべきは、1件ごとの点数ではなく、次の3つだ。
「うちはHighが3件あるがCriticalはない」は、安心材料ではない。深刻度は部品の点数であって、組み立て後の点数ではない。
40年分の歴史を6行の表に圧縮すると、対策技術は確実に進歩しているのに、古典的な型は一つも退場していない、という事実が残る。新しい技術が登場しても、古い脆弱性が消えるわけではない。同じ型が、新しい場所に移って現れる。そして本当の危険度は、その脆弱性が何と隣り合っているかで変わる。
だから脆弱性管理で問うべきは「このCVEは何点か」だけではない。「この型は、うちのどの層に、他の何と隣り合って出ているか」である。
参考(一次情報)
Aikido Community Japan
公開日: 2026/8/23
最終更新: 2026/8/23
セキュリティの最新情報をお届けします。