AIエージェントに10本のPRを作らせたら、9本に穴があった。これは推測でも警告でもなく、実験の結果だ。
2026年3月、セキュリティ企業DryRun Securityが「The Agentic Coding Security Report」を公開した。Claude Code、OpenAI Codex、Google Geminiの3エージェントに実際にアプリを作らせ、生成されたPRをセキュリティスキャナーにかけた。30件のPRを38回スキャンして見つかったセキュリティ問題は143件。そのうち26件(87%)のPRに少なくとも1つの脆弱性が含まれていた。完全にセキュアなアプリを作ったエージェントはゼロだった。
「動くから大丈夫」が通用しない理由は、この数字に凝縮されている。
何を、どう調べたのか
DryRun Securityが実験に使ったのは、2種類のアプリだ。家族のアレルギー情報を管理するWebアプリ「FaMerAgen」と、ブラウザで動くレーシングゲーム「Road Fury」。どちらもバイブコーディングで作られそうな、身近なアプリの構成だ。
この2本のアプリを、Claude Code(Sonnet 4.6)、OpenAI Codex(GPT 5.2)、Google Gemini(2.5 Pro)の3エージェントにそれぞれ作らせた。各エージェントは複数のPRに分けてコードを提出し、それをDryRunの自動セキュリティスキャナーが検査した。
見えてきたのは、特定のエージェントだけが失敗するわけではないという事実だ。3つ全てのエージェントが、同じカテゴリの脆弱性を繰り返し作った。
エージェントが繰り返す10の失敗
DryRun Securityが記録した脆弱性は10のカテゴリに分類できる。全エージェントで観測されたパターンだ。
1. 壊れたアクセス制御(最も普遍的)
全エージェント、両アプリで一貫して発生した。認証はある。でも認可がない——ログインしていれば他人のデータも操作できる、というパターンだ。Webアプリの重大セキュリティリスクを定義したOWASP Top 10でも第1位に位置づけられる脆弱性だが、エージェントはほぼ確実にこれを作る。
2. ビジネスロジック欠陥
検証をクライアント側(ブラウザ側)だけで行い、サーバーで再検証しない。ゲームのスコアや残高をクライアントから受け入れる実装がここに当たる。ブラウザの開発者ツールを開ける人間なら誰でも改ざんできる。
3. OAuth実装の欠陥
OAuth(「Googleでログイン」「GitHubでログイン」のような外部サービス経由の認証プロトコル)のstateパラメータが抜けていたり、アカウントのリンク処理が安全でない実装になっていた。全エージェントのWebアプリに発生した。
4. WebSocket認証ギャップ
全ゲームコードベースで確認された。REST APIには認証ミドルウェアを正しく設定するのに、WebSocket接続には認証チェックを繋がなかった。玄関ドアには鍵をかけたが、窓は全開のままというパターンだ。
5. レート制限ギャップ
レート制限のミドルウェアを書いた。でも実際にアプリに繋がなかった。全コードベースで同じことが起きた。火災報知器を壁に取り付けたが、電源に繋がなかったのと同じだ。
6. JWT秘密鍵管理の脆弱性
JWT(JSON Web Token)はログイン済みユーザーの情報を暗号化した文字列で、「この人は認証済みだ」という証明書として使われる。そのJWTを署名するための秘密鍵がハードコードされたフォールバック値として残された。攻撃者はこの鍵を使って、認証情報なしで有効なトークンを偽造できる。
7〜10. その他の認証弱点
2FA(二要素認証:パスワードに加えてSMSコードなどを要求するセキュリティ機能)バイパス脆弱性、ユーザー列挙問題、セッション管理の失敗、クライアントサイド信頼の問題が残りのカテゴリを占める。
全エージェントの最終成果物に共通して残った弱点が4つある——安全でないJWT検証、ブルートフォース保護の欠如、トークンリプレイ攻撃への露出、安全でないリフレッシュトークンCookieのデフォルト。エージェントの種類ではなく、エージェントという仕組み自体の限界として現れている。
「繋いだつもり」が積み重なる
DryRun研究で特に目立ったのは、「書いたが繋がなかった」というパターンだ。コードを読めば存在は確認できる。でも実際には機能していない。
レート制限の例を見てほしい。
// ❌ エージェントが書いたコード:定義されているが繋がれていない
const rateLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
});
// app.use(rateLimiter) を呼ぶのを忘れている
app.post('/login', async (req, res) => {
// 無制限にブルートフォース可能
});
// ✅ 正しい:ミドルウェアを適切に接続する
const rateLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
});
app.use('/login', rateLimiter); // この1行が抜けていた
app.post('/login', async (req, res) => {
// レート制限が効いている
});
全エージェントがレート制限のコードを書いた。全エージェントがアプリに繋がなかった。コードレビューで「レート制限のコードがある」を確認しても意味がない。「ルートに接続されているか」まで確認しなければ守れていない。
WebSocket認証でも同じことが起きた。
// ❌ エージェントが書いたコード:RESTは守られているがWebSocketは無防備
app.use('/api', authenticateToken); // REST APIは認証済み
const wss = new WebSocketServer({ server });
wss.on('connection', (ws) => {
// WebSocket接続には認証チェックなし。誰でも繋がれる
ws.on('message', (data) => {
// ゲームの状態更新、スコア改ざん可能
});
});
// ✅ 正しい:WebSocketアップグレード時に認証を確認
const wss = new WebSocketServer({ noServer: true });
server.on('upgrade', (request, socket, head) => {
const token = getTokenFromRequest(request);
if (!verifyToken(token)) {
socket.destroy();
return;
}
wss.handleUpgrade(request, socket, head, (ws) => {
wss.emit('connection', ws, request);
});
});
REST APIとWebSocketを別々のコンテキストで実装してしまう。REST用の認証ロジックはあるが、WebSocketの接続確立時にそれを呼び出していない。機能していない安全装置は、ないのと同じだ。
なぜ設計の問題になるのか
「ミドルウェアを書いたのに繋がなかった」「REST用の認証を書いたのにWebSocketに適用しなかった」——これはコードの書き間違いではなく、設計判断の問題だ。
エージェントはタスクを分解して実装する。「ログイン機能を作る」というタスクでは認証コードを書く。でも「レート制限が必要」と明示的に言わなければ、それは別タスクとして処理されず、追加されても繋がれない。
DryRun CEOのJames Wickettはこう述べている。「AIコーディングエージェントは信じられないスピードで動くソフトウェアを作れるが、セキュリティはデフォルトの思考に入っていない。エージェントはセキュリティコンポーネントを追加し忘れるか、認証ロジックに欠陥を作ることが多い」。
そして続ける。「エージェントの使用を止めることが答えではない。セキュリティを意識しているとデフォルトで仮定するのを止めることが答えだ」。
エージェントは施錠業者ではない。「動くものを作る専門家」だ。10部屋に施錠を頼んだ業者が9部屋の鍵をかけ忘れる——それを防ぐのは依頼する側の責任になる。

3エージェントの比較
研究では3エージェントの最終成果物を個別に評価している。Webアプリ(FaMerAgen)の結果を見ると、差は出た。
DryRun研究レポートによれば、Claude Code(Sonnet 4.6)の最終成果物には13件の問題が残り、3エージェント中最多の未解決高深刻度脆弱性が確認された。他のエージェントにない2FAバイパスも導入した。OpenAI Codex(GPT 5.2)は8件で最少。修正行動も最も積極的だった。Google Gemini(2.5 Pro)は11件。早期に複数の問題を導入したが、後続のPRで一部を修正した。
順位をつけることに意味はあまりない。最も「成績が良かった」Codexでも8件の問題が残っている。スコアではなく「全エージェントが脆弱性を残した」という事実の方が重要だ。
特定のエージェントを選べばセキュアになる、という話ではない。問題はエージェントの種類ではなく、エージェントが「セキュリティを意識して設計する」という作業が苦手なことだ。
業界全体で起きていること
DryRunの研究は孤立したデータではない。
Veracode 2025 GenAI Code Security Reportは、100以上のLLMで80のコーディングタスクをテストした結果、AIが生成したコードの45%がOWASP Top 10に分類される脆弱性を含んでいたと報告している。JavaではXSS(クロスサイトスクリプティング:第三者の悪意あるスクリプトをページに埋め込む攻撃手法)のテストで86%が防御に失敗した。
Apiiroの2025年9月のレポートはFortune 50企業のリポジトリを分析し、AIコーディングアシスタントの導入でPrivilege Escalation(権限昇格:一般ユーザーが管理者権限を不正に取得する攻撃経路)が322%増加、アーキテクチャ設計欠陥が153%増加したと記録している。速度は上がった。脆弱性も一緒に上がった。
Cisco State of AI Security 2026レポートによれば、83%の組織がエージェントAIを業務機能に展開する予定だが、安全に活用する準備ができていると感じているのはわずか29%だ。54ポイントのギャップがある。30,000以上のAIエージェントスキルを分析したCiscoの研究者は、4分の1以上に少なくとも1つの脆弱性が含まれていることを発見した。
Aikido Security State of AI in Security & Development 2026(450人調査)では、全本番コードの24%がAIツール製になっており、5社に1社がAI生成コードにリンクした重大侵害を経験したと答えている。
どのレポートも同じ結論に向かっている。AIは速くコードを書く。セキュリティはデフォルトで付いてこない。
何をすべきか
DryRunの研究が示唆する対策は、エージェントへの不信ではなく、自動セキュリティスキャンとの組み合わせだ。
エージェントが作ったPRを人間がレビューするだけでは不十分だ。前述のとおり、「コードが存在すること」と「機能していること」は別の話で、コードを読んで確認できない問題がある。
実践的なアプローチは、CIパイプラインへの自動セキュリティスキャンの統合だ。PRが作られるたびにスキャナーが走り、「ミドルウェアが繋がれているか」「認証フローに抜けがないか」を機械的に確認する。エージェントが苦手な部分を別のツールが補う構成だ。
もう一つは、セキュリティ要件をプロンプトに明示することだ。「認証機能を作って」ではなく「認証機能を作って。ブルートフォース対策のレート制限、WebSocket接続への認証適用、JWTの秘密鍵をハードコードしないことを含めて」と指定する。エージェントは言われたことは実装する。言われなかったことは実装しない。
「最後にセキュリティチェックをお願い」はあまり効かない。エージェントが作ったコードをエージェント自身にレビューさせると、作ったときと同じ視点で確認するため見落としが出る。自動スキャナーという外部の目が必要だ。
動くことと、安全であることは別の仕事だ
エージェントが作ったアプリが動いている。ログインもできるし、データも保存できる。見た目も完成している。でも87%のケースで、何かが壊れている。
壊れているのは見えるところではない。認証ミドルウェアが書いてあるのに繋がっていない。レート制限のコードがあるのに機能していない。コードレビューで「ある」を確認しても意味がなく、「機能しているか」を外部から検証しなければわからない。
エージェントを使うことをやめる必要はない。ただ、「セキュリティを意識して作っているはず」という仮定を捨てる必要がある。