
エンジニアの仕事は、コードを書くことから「コードを検証すること」へと大きな転換点を迎えています。AIの普及により、実装のスピードは飛躍的に向上しました。しかし、その影では「動くものの壊れやすい」コードが量産されるリスクも浮き彫りになっています。本記事では、AI生成コード時代に不可欠な「壊し上手」のスキルについて詳しく解説します。AIが見落としがちな死角を特定し、それを組織の武器として昇華させるための具体的なチェックリストや、開発プロセスへの組み込み方を提案します。
【関連記事】システム開発の新常識!Copilotの活用でエンジニアの役割はどう変わる?

コードのAI生成は「速い」けど「脆い」
プログラミングの世界において、生成AIの登場は大きな革命でした。GitHub Copilotをはじめとする支援ツールの導入により、コードを書き上げるまでの時間は劇的に短縮されています。しかし、この速さの裏側には、これまでの開発現場では経験したことのないような、新しい種類の脆さが潜んでいます。
実装スピードの向上と安全性のトレードオフ
近年の調査によれば、AI支援ツールの活用によって開発タスクの完了速度が約55.8%向上したという結果が出ています。以前なら数時間かかっていたHTTPサーバーの実装や複雑なアルゴリズムの雛形も、今では数分、あるいは数秒で目の前に現れます。ここで私たちが意識すべきなのは、AIは正しさや安全性を自動的に担保してくれる存在ではないという事実です。
AIは過去の膨大な学習データから「それらしいコード」を生成することには長けていますが、そのコードが現在のプロジェクトのセキュリティ要件を完璧に満たしているかまでは判断できません。開発スピードが上がるほど人間による検証が追いつかなくなり、結果として「検証の先送り」が発生しています。これは、納期に追われる現場において深刻な問題を引き起こす火種となります。
AIが生成するコードに潜むセキュリティの罠
AIの支援を受けて書かれたコードは、人間が自力で書いたコードよりもセキュリティ面で脆弱になりやすいという研究結果があります。さらに厄介なのは、AIを使った開発者は、自分の書いたコードが実際よりも安全であると誤認してしまう傾向にある点です。AIが提示するコードは一見すると洗練されており、バグなど微塵もなさそうに見えてしまいます。
例えば、SQLインジェクションやクロスサイトスクリプティングといった古典的な脆弱性が、AIの生成したコードの中に巧妙に紛れ込んでいるケースは少なくありません。AIは「書き手」としての能力を最大化しますが、「守り手」としての視点は不足しがちです。私たちが手に入れたのは超高速な自動筆記ツールであり、完璧な品質管理官ではないことを認識しておく必要があります。
現場で起きている「信じているフリ」というギャップ
多くのエンジニアは、アンケートにおいて「AIが生成したコードが常に正しいとは思っていない」と回答しています。しかし、実際の行動レベルではどうでしょうか。開発現場の実態を調査すると、AIのコードを疑っていると言いつつも、半分程度のエンジニアしかコードを詳細に確認せずにコミットしていないという衝撃的なギャップが存在します。
AIが出力するコードがあまりに自然で大量であるため、人間側がレビューのコストを支払い切れなくなっているのが原因の一つです。「AIが書いたのだから大丈夫だろう」という根拠のない信頼が、本来行われるべきコードレビューの目を曇らせています。一見完成しているように見えるそのコードは、実は基礎部分に深刻な欠陥を抱えたまま建てられた「欠陥建築」のようなものかもしれません。
壊し方を知らなければ速さは凶器になる
AIはコードを書くことは得意ですが、そのコードがどのように壊れるかまでは面倒を見てくれません。エンジニアに求められる役割は、単にキーボードを叩いて文字を羅列することから、AIが提示した案をいかにして徹底的に壊し、弱点を見つけ出すかという検証の領域へとシフトしています。
検証を後回しにしてスピードだけを追い求めた結果、本番環境で致命的な障害が発生しては元も子もありません。次章では、AIが見落としやすく、私たちが重点的にチェックすべき壊れ方のポイントを具体的なリストとして整理します。この「AIが生成したシステムを壊す」という視点こそが、AI時代のエンジニアが持つべき強力な武器となります。
【参考】Do Users Write More Insecure Code with AI Assistants?
AIが見落としやすい「壊し方」とは

AIが生成したコードをそのまま受け入れることは、安全装置を確認せずに機械を動かすようなものです。AIは、ユーザーが想定通りの操作を行った場合の挙動を組み立てることは得意ですが、悪意のある操作やネットワークの不安定さといった現実的なトラブルを考慮に入れるのが苦手です。ここでは、エンジニアがすぐに使える具体的な壊し方の観点を整理します。
UI操作の暴発と二重送信の穴
ウェブアプリケーションにおいて発生しやすく、かつ重大な不具合につながるのが、ボタンの連打やダブルクリックによる操作の暴発です。AIは往々にして、1回のリクエストで処理が完了することを前提としたコードを書きます。しかし現実のユーザーは、反応が遅ければボタンを連打しますし、戻るボタンで前のページに戻ってから再度送信ボタンを押すこともあります。
- 起きる現象: 決済ボタンを連打すると、二重に請求が発生してしまう。
- なぜAIが見落とすか: 状態管理による制御を周辺的な処理とみなし、ロジックの核となる部分のみを生成するため。
- 最小の再現手順: 決済画面で送信ボタンを素早く3回クリックする。
- 対策の方向性: フロントエンドでのボタン無効化に加え、サーバー側での冪等性の確保が必要になります。
通信断とリトライによるデータの重複
モバイル回線を使用している場合、電波の瞬断は日常的に起こります。処理の途中でタイムアウトが発生し、ブラウザやアプリが自動的に再試行を行った際、AIの生成コードは同じ処理が2回走ることを想定していないことがよくあります。これにより、在庫が過剰に減ったり、ポイントが二重に付与されたりといった不整合が生じます。
- 起きる現象: 通信エラー後の自動リトライにより、データベースに重複したレコードが作成される。
- なぜAIが見落とすか: ネットワークを常に安定しているものとして抽象化して考えてしまうため。
- 最小の再現手順: リクエスト送信直後に通信を遮断し、再送が発生した際の結果を確認する。
- 対策の方向性: リクエストごとに一意な識別子を付与する冪等キーの導入や、PRGパターンの適用による重複送信の回避が有効です。
状態管理と同時実行の競合
複数のユーザーが同時に同じデータを更新しようとした際、AIが生成したシンプルな更新ロジックはレースコンディションを引き起こします。後から更新したデータで上書きされたり、数値の加算が正しく行われなかったりする問題です。これはローカル環境のテストでは表面化しにくいため、見落とされると非常に厄介なバグとなります。
- 起きる現象: 残高1000円のアカウントに対し、2つの端末から同時に600円の引き落としを行うと、両方成功して残高がマイナスになる。
- なぜAIが見落とすか: 単一のスレッドや直列的な処理フローでロジックを組み立てる傾向があるため。
- 最小の再現手順: 複数のブラウザタブを開き、ほぼ同時に更新リクエストを送信する。
- 対策の方向性: データベースのロック機構や楽観的排他制御を適切に設計に組み込む必要があります。
境界値と異常系への想像力
AIは標準的な入力を想定したコードは綺麗に書きますが、極端な値や不正な形式のデータが入ってきた時の挙動は甘くなりがちです。データが0件の場合、最大文字数を超える入力、あるいは絵文字や改行コードが含まれた文字列など、システムを壊しにくる入力に対して、生成されたバリデーションが機能しないケースが多々あります。
- 起きる現象: 想定外の長さの文字列を入力すると、画面レイアウトが崩れたり、データベースの制約エラーでシステムが停止したりする。
- なぜAIが見落とすか: バリデーションを付加的なものと捉え、入力値の性質を深く考察せずに定型的なコードを出力するため。
- 最小の再現手順: 入力フォームに数万文字のテキストや制御文字を貼り付けて送信する。
- 対策の方向性: プロパティベースのテストという考え方を取り入れ、ランダムな入力を大量に試行して不変の性質を検証するアプローチが重要です。
セキュリティの不備
AIが生成するコードにおいて最も危険なのが認可制御の不備です。ログインしていることは確認していても、そのデータにアクセスする権限があるかという細かいチェックが漏れていることがあります。これはOWASPの重大リスクでも常に上位にランクインする、一般的かつ深刻な穴です。
- 起きる現象: URLのID部分(例:/user/123)を書き換えるだけで、他人の個人情報が表示されてしまう。
- なぜAIが見落とすか: コンテキストを理解した権限設計は、コードの断片からは判断しにくいため。
- 最小の再現手順: 別のアカウントでログインした状態で、他人のリソースIDを直接URLに入力する。
- 対策の方向性: 設計段階で認可モデルを明確化し、テストコードで権限外アクセスの拒否を網羅的に検証する必要があります。
「壊し上手」というエンジニアスキル
壊し上手であることは、単なる個人の適性ではありません。AIがコードを書く現代において、それは再現可能なプロセスとして定義されるべきエンジニアの核心的なスキルです。個人の注意深さに頼るのではなく、仕組みとして検証を開発フローに組み込む方法を考えましょう。
vibe(生成)→ verify(検証)を習慣にする
AIが生成したコードに対し、「なんとなく良さそう」という雰囲気(vibe)だけで承認してはいけません。生成されたものを徹底的に疑い、検証(verify)する工程を、開発における不可欠なプロセスとして確立する必要があります。プルリクエストのレビューは、コードを眺める時間ではなく、チェックリストに基づいた「攻撃の時間」に変えるべきです。
具体的には、CI/CDパイプラインの中にセキュリティスキャンや自動テストを組み込むのはもちろん、人間によるレビューのゲートを厳格化することが求められます。AIを活用して浮いた時間は、より高度なシナリオテストやセキュリティの検討に充てましょう。この意識改革こそが、AI時代のプロフェッショナルへの第一歩となります。
セキュア開発をフレームワークに落とし込む
セキュリティや品質の担保を個人の力量に任せると、必ずムラが生じます。そこで、NISTが提唱する「セキュアソフトウェア開発フレームワーク(SSDF)」のような考え方を実務に取り入れるのが効果的です。これはソフトウェアのライフサイクル全体を通じてセキュリティを考慮するためのガイドラインであり、AI時代の開発プロセスを再定義する大きな助けとなります。
- 準備: 組織として安全な開発を行うためのポリシーを策定する。
- 保護: コードの改ざんを防ぎ、リリース後の安全性を維持する仕組みを作る。
- 作成: 脆弱性の少ないコードを生成し、早期に不備を発見する。
- 対応: 発見された脆弱性に対し、迅速に修正と再発防止を行う。
このようにセキュアな開発を仕組み化することで、AIが吐き出した未熟なコードが本番環境へ流出するのを防ぐ多重の防御壁を構築できます。
壊し方の自動化:fuzzingとカオス工学
人間の手による検証には限界があります。そこで活用したいのが、不規則なデータを大量に送り込んでバグを炙り出す「fuzzing(ファジング)」や、あえて障害を注入してシステムの耐性を試す「カオス工学」の手法です。これらは壊すことを目的としたエンジニアリングであり、AI生成コードの脆さを暴くために非常に強力なツールとなります。
例えば、重要な決済機能に対しては、意図的にネットワーク遅延を発生させたり、異常なパケットを注入したりするテストを自動化します。また、冪等性や重複排除が正しく機能しているかを検証するために、同じリクエストを数千回同時並行で送り込むような負荷テストも有効です。これらは単に動くことを確認するテストではなく、システムの限界を知るための実験です。こうした実験を通じて得られた知見こそが、AI時代のエンジニアの価値を裏付けます。
今日からできる「壊し上手」への3ステップ
壊し上手への道は今日から始めることができます。特別なツールを導入する前に、まずは思考プロセスをアップデートしましょう。以下の3つのアクションを提案します。
- 壊れそうなパターンの言語化: 自分が担当している機能において、ユーザーがどう操作したら壊れるか、通信がどう切れたら不整合が起きるかをリストアップします。
- PRテンプレートの活用: プルリクエストのテンプレートに、「連打対策」「リロード時の挙動」「認可チェック」といった確認項目を必須として追加します。
- 成果指標の転換: 単にバグを見つけた数を誇るのではなく、二度と同じバグが起きない仕組みを導入した数を自分の成果として定義します。
これからのエンジニア像は、誰よりも速くコードを書ける人ではありません。AIがもたらす圧倒的なスピードを制御し、その影にあるリスクを誰よりも早く見つけ、壊して確かめられる人です。速さを武器にするか、それとも速さに振り回されるか。その分かれ道は、エンジニアの「壊す能力」にかかっています。
AI時代のエンジニアの真価とは

AIは私たちの開発体験を劇的に変えましたが、同時に見えないリスクという新しい課題も突きつけました。連打やリロード、通信断、同時実行、そして認可の不備といった、AIが自動では埋めてくれない落とし穴を先回りして潰す力が求められています。
エンジニアの真価は、仕様の穴を突き、システムの壊れ方を熟知し、運用の死角を排除する検証力に集約されていくでしょう。vibe(生成)→ verify(検証)というサイクルを習慣化し、壊し方のチェックリストを日々の工程に組み込むことで、AIのスピードを真に自分のものにできます。検証力を磨き、「AIに振り回される」側から「AIを乗りこなす」側へ移ることが、今日のエンジニアに求められています。
