生成AIでコードを書く速度は、もう後戻りできないレベルに上がりました。私自身、一人 × 生成AI(Claude Code)で、経済産業大臣賞を受賞したB2B SaaSや本番二重課金0件の決済基盤を作ってきました。だからこそ、はっきり言えます——AIは速いが、放っておくと脆弱性も同じ速さで量産します。
これは感覚論ではなく、研究で裏付けられた事実です。
- AIアシスタントを使った開発者は、使わない開発者より脆弱なコードを書きやすい。 しかも、「自分は安全なコードを書けた」と過信する傾向がある(Stanford大学、Perryら 2022)。
- GitHub Copilotが生成したコードの約40%が、セキュリティ上重要な89シナリオで悪用可能な脆弱性を含んでいた(NYU、Pearceら 2021「Asleep at the Keyboard?」)。
しかし、これは「AIを使うな」という話ではありません。 私の結論はその逆です。AIの速さは、リリース前の検証ゲートで負債を相殺すれば、本番品質と両立できます。 鍵は「AIに実装を任せ、人間が仕様決定と検証を握る」という役割分担です。本記事は、その検証=AI生成コードの脆弱性診断を、データ・新リスク・実コード・検証ゲート設計まで、一気通貫で示します。
1. なぜAIは脆弱性を生むのか — 3つの構造的理由
AIがバグを出すのは「賢くないから」ではありません。構造的な理由があり、それを理解すると診断の的が絞れます。
- 訓練データの欠陥パターンを再生産する。 AIは世の中のコードを学習しています。そこには安全でないコードも大量に含まれるため、確率的に「よくある書き方」=「よくある脆弱なパターン」を出力します。SQLの文字列連結や
dangerouslySetInnerHTMLの直挿入は、その典型です。 - 文脈(あなたの事業ルール)を知らない。 AIは「このAPIにアクセスしてよいのは誰か」を知りません。だから認可チェックを平気で省略します。これは後述するTOP5の第1位です。
- ハルシネーション(幻覚)を起こす。 存在しない関数・存在しないパッケージを、自信満々に生成します。これが次節の新リスク「slopsquatting」の温床です。
つまりAIの弱点は、**「構造的欠陥の再生産」と「文脈の欠如」と「幻覚」**の3つ。診断は、この3つを狙い撃ちにします。
2. AI特有の新リスク「slopsquatting」— 幻覚がサプライチェーン攻撃になる
2025年に名付けられた、AI時代に固有の脆弱性が slopsquatting です。仕組みはこうです。
- AIが、実在しないパッケージ名を「これをインストールせよ」と提案する。
- 攻撃者が、その幻覚パッケージ名を先回りしてnpm/PyPIに登録し、悪意あるコードを仕込む。
- 開発者がAIの言うままに
npm installすると、悪意あるコードが本番に取り込まれる。
これは絵空事ではありません。研究によれば、16の生成モデルで作った223万サンプルのうち19.7%が、存在しないパッケージ名を含んでいました。さらに同じ幻覚が再現しやすい(同一プロンプトの再実行で43%が毎回同じ幻覚名を出した)ため、攻撃者は「どの名前を登録すれば刺さるか」を予測できます(DevOps.com / Cloud Security Alliance)。
これは OWASP Top 10:2025 で新設・拡大された A03 Software Supply Chain Failures に直撃する、AI時代の最新リスクです。防御は次の3点です。
# ① 提案されたパッケージが「実在し、まともか」を install 前に検証する
npm view <package-name> # 存在しない/極端に新しい/DL数が異常に少ないものは疑う
# ② lockfile を信頼の唯一の源にし、不意の解決を防ぐ(CIは必ず ci を使う)
npm ci # package-lock.json に完全一致させる(install ではなく ci)
# ③ 依存を毎回スキャン(slopsquattingは「見覚えのない依存の増加」として現れる)
npm audit --audit-level=moderate
npx osv-scanner scan --lockfile=package-lock.json
運用のコツ: AIに依存追加を提案されたら、「その名前は本当に実在するか」を人間が一度確認するだけで、slopsquattingの大半は防げます。
package.jsonの差分レビューで、見覚えのないパッケージが増えていないかを必ず見てください。
3. AIが量産しがちな脆弱性TOP5 と、その潰し方
実務でAI生成コードを診ると、繰り返し同じ穴が出ます。頻出順のTOP5と、修正前後のコードを示します。
① 認可の欠落(IDOR / OWASP A01)— 最頻出かつ最重大
AIは認証(ログイン済みか)は書きますが、認可(その人がそのデータの持ち主か)を省略します。
// ❌ AIがよく書く:ログインは確認するが「所有者か」を確認しない → 他人のデータが見える
export async function GET(_req: Request, { params }: { params: { id: string } }) {
const order = await db.order.findUnique({ where: { id: params.id } });
return Response.json(order); // 他人のIDを入れれば、他人の注文が返る(IDOR)
}
// ✅ 所有権でフィルタする(「誰が所有するか」は事業ルール=人間が指定すべき不変条件)
export async function GET(req: Request, { params }: { params: { id: string } }) {
const userId = await requireUserId(req); // 認証
const order = await db.order.findFirst({
where: { id: params.id, ownerId: userId }, // 認可:所有権で絞る
});
if (!order) return Response.json({ error: "not found" }, { status: 404 });
return Response.json(order);
}
② 入力検証の漏れ(OWASP A05)
AIは「ハッピーパス」を書きがちで、境界での検証を飛ばすことがあります。外部入力は信頼境界で必ず検証します。
// ✅ システムの境界(外から来る値)でZod検証し、型を絞ってから使う
const Body = z.object({ email: z.string().email(), age: z.number().int().min(0).max(150) });
const parsed = Body.safeParse(await request.json());
if (!parsed.success) return Response.json({ error: "invalid" }, { status: 400 });
③ 秘密のハードコード(OWASP A02/A03)
AIはサンプルとしてAPIキーをコードに直書きすることがあります。サーバー専用の秘密はprocess.env経由に限定し、NEXT_PUBLIC_との混在を型で防ぎます(詳細)。Gitleaks+GitHubのPush Protectionで物理的に止めます。
④ 古い / 存在しない依存(OWASP A03)
AIは訓練データ時点の古いバージョンや、前節の幻覚パッケージを提案します。npm audit・Dependabot・存在検証で潰します。
⑤ 安全でないデフォルト設定(OWASP A02)
CORSを*に開く、CookieにHttpOnly/Secureを付け忘れる、エラーでスタックトレースを返す——AIは「動く最小構成」を優先するため、安全側のデフォルトを外しがちです。セキュリティヘッダー/CSPやCORSはミドルウェアで一括強化します。
4. リリース前チェックリスト — AI生成コードを4層で診る
AI生成コードは、マージ前に必ず4層の自動診断を通すのが基本です。前述のTOP5は、この4層でほぼ捕捉できます(認可=①を除く。①は第6節へ)。
| 層 | 狙うAIの弱点 | コマンド | 対応OWASP |
|---|---|---|---|
| SCA | 幻覚・古い依存(slopsquatting) | npm ci + npm audit + OSV-Scanner | A03 |
| シークレット | 鍵のハードコード | gitleaks + Push Protection | A02 |
| SAST | 構造的欠陥(注入・設定) | semgrep scan --config=auto | A05 ほか |
| DAST | 実行時の挙動(反射XSS・ヘッダー) | ZAP zap-baseline.py | A01/A05/A02 |
この4層をGitHub ActionsでPRゲート化すれば、AIがどれだけ速くコードを生んでも、脆弱性はマージ前に自動でブロックされます。具体的なCIワークフロー(SARIF集約まで)はCI統合の手順記事に、4層の実装詳細はOWASP公式手法のハンズオン記事にまとめています。「AIで速く書く」と「ゲートで安全に止める」はセットにして初めて成立します。
5. 人間の検証ゲートを設計する — 「AIに実装、人間に仕様と検証」
ツールゲートは必要条件ですが、十分ではありません。生成の速さを本番品質に変える鍵は、人間が握るべき2点を手放さないことです。
- 仕様の決定は人間が握る。 「誰が何を所有し、どの操作を許されるか」「金額・数量・状態遷移の不変条件は何か」——これらはAIに決めさせてはいけない事業ルールです。AIには「この仕様を満たす実装」を任せます。
- 受け入れ条件をテストに落とす。 「他人のIDで他人の注文が見えないこと」をテストとして書けば、AIが認可を省略してもテストが落ちて検出できます。検証パスを先に用意するのが、AI時代の最大の品質レバーです。
// ✅ 認可の不変条件を「テスト」として固定する(AIが省略しても落ちる)
it("他人のリソースは取得できない(IDOR防止)", async () => {
const res = await GET(reqAs(userA), { params: { id: orderOwnedByUserB.id } });
expect(res.status).toBe(404); // 200で中身が返ったら認可バグ
});
これは私が一貫して使っているワークフローそのものです。探索 → 計画 → 実装 → 検証の4フェーズで、AIに速度を出させつつ、各ゲートで人間が仕様と安全を確認する。AI駆動開発の品質ゲート全体像はAI駆動開発の品質ゲート記事で扱っています。
6. AIが原理的に作れない安全 — 認可・業務ロジックは人間の領域
最後に、最も重要な一線です。どれだけ優秀なAIでも、診断ツールでも、原理的に保証できない安全があります。 それが**認可(A01)・テナント分離・業務ロジック(OWASP WSTG 4.5 / 4.10)**です。
理由は、第1節で触れた「文脈の欠如」に行き着きます。「この請求書を見てよいのは誰か」「この割引は何回まで使えるか」は、**あなたの事業ルールの"意味"**であり、AIもスキャナもその意味を知りません。だから、認可の欠落を「欠落」だと判定できない。SQLインジェクションが「どんなアプリでも同じ構造的欠陥」なのとは対照的です。
| AI・ツールが守れる(水平) | 人間しか守れない(垂直) |
|---|---|
| 注入・設定ミス・既知CVE・秘密の混入 | 認可/IDOR・テナント分離 |
| 構造的・既知パターンの欠陥 | 業務ロジック(数量・価格・状態遷移の悪用) |
ここから先は、ツールゲートではなく手動の認可レビュー・監査の領域です。とりわけ**「AIで大量にコードを生成した直後のリリース前」は、認可・業務ロジックの抜けが最も入りやすい**タイミング——監査を入れる最大の好機です。垂直リスクの検出と多層防御はIDOR・認可欠陥の検出記事、監査の範囲と費用感はセキュリティ監査は何を見るのかを参照してください。
まとめ — AIの速さを、検証で本番品質に変える
- AIは脆弱性を量産する(Stanford:過信、NYU:約40%が脆弱)。だが速さは検証で相殺できる。
- AI時代の新リスク slopsquatting(幻覚パッケージ=A03)。lockfile固定・存在検証・依存スキャンで防ぐ。
- AIが量産するTOP5(認可欠落・入力検証漏れ・秘密ハードコード・古い/存在しない依存・危険なデフォルト)を、修正前後のパターンで根治する。
- リリース前に4層で診る(SCA→シークレット→SAST→DAST)。無料ツールでPRゲート化できる。
- 人間は仕様決定と検証を握る。認可・業務ロジックはAIに渡さない。AIが作れない安全=監査の領域。
「AIで速く作る」ことと「安全に出荷する」ことは、対立しません。速さの裏に生まれる負債を、リリース前の検証ゲートで毎回相殺する——この設計さえあれば、生成AIは最強の武器になります。私自身が一人 × 生成AIで本番品質のプロダクトを作り続けている、まさにその方法です。AIで生成したアプリのリリース前診断や、認可・業務ロジックの監査が必要になったら、まずは無料OSS Aegis で現状を可視化するところからご相談ください。