入力欄は、外の世界からあなたのアプリに「文字を送り込める口」です。その文字が、データとしてではなく命令として扱われてしまうと、データベースが思わぬ動きをしたり、他の利用者の画面で勝手なプログラムが動いたりします。この章では、仕組みを図で理解したうえで、無害な文字列だけを使って自分のアプリの入力欄を確かめます。
この章の学習目標
- インジェクションとクロスサイトスクリプティング(XSS)が「データと命令の混同」であることを、図で説明できるようになる
- 無害な文字列(太字タグ、長い文字列、全角数字など)で、自分のアプリの入力欄の扱いを確かめられるようになる
- 「安全な方法を使っているか」をAIに確認させ、その報告を自分で読めるようになる
入力欄は「命令を送り込める口」
伝票の摘要欄を思い浮かべてください。そこに書かれた文字が、会計システムに取り込まれたとき、文字としてではなく「この仕訳を削除せよ」という命令として実行されてしまったらどうなるでしょう。摘要欄に書けるのは起票者です。起票者が会計システムに命令できることになってしまいます。入力欄の安全確認とは、「摘要欄の文字は、どこまで行っても文字のまま扱われるか」を確かめることです。
論文で2位だった「インジェクション」(199件、16.78%)は、まさにこの問題です。インジェクション(injection。注入)とは、利用者が入力した文字が、サーバーがデータベースなどに送る命令の一部に混ざり込み、命令の意味が変わってしまうことを指します。
もうひとつ、XSS(クロスサイトスクリプティング)という不備があります。こちらは、入力した文字が他の利用者の画面にそのまま表示され、ブラウザがそれを「実行するプログラム」として解釈してしまうものです。OWASP Top 10:2025では、XSSはA05「インジェクション」の一種として分類されています。
守り方は「混ぜない」と「そのまま出さない」
対策は、攻撃の種類を暗記することではありません。次の2つの原則が守られていれば、ほとんどのインジェクションとXSSは成立しません。
命令とデータを分けて渡す
データベースへの命令を文字のつなぎ合わせで組み立てる代わりに、「命令の型」と「はめ込むデータ」を別々に渡す方法があります。プレースホルダー付きのクエリ(パラメータ化クエリ)と呼ばれ、OWASPのSQL Injection Prevention Cheat Sheetが第一の対策として挙げているものです。Supabaseのクライアントライブラリや、一般的なORM(データベースを扱う部品)は、通常この方式で動きます。危ないのは、AIが「SQLを文字列でつなげて作る」コードを書いた場合です。
表示するときにエスケープする
利用者の入力を画面に出すとき、< や > のような記号を、ブラウザが「タグ」と解釈しない形に変換することをエスケープと呼びます。Reactをはじめ多くのフレームワークは、標準でこれを行います。例外は、「HTMLをそのまま挿入する」ための機能を使った場所です。Reactなら dangerouslySetInnerHTML という、わざわざ危険だと名前に書いてある機能がそれに当たります。AIはリッチな表示を実現するために、これを気軽に使うことがあります。
入力の検証は補助
長さ、形式、文字種の確認(検証)も大切ですが、これは上の2つの代わりにはなりません。検証は「おかしな入力を早めに弾く」ための補助であり、本体は「混ぜない」「そのまま出さない」です。IPAの「安全なウェブサイトの作り方」でも、SQLインジェクションとクロスサイト・スクリプティングは代表的な脆弱性として取り上げられ、根本的解決と保険的対策が分けて説明されています。
ここはAI任せにできない:Veracodeの数字
基礎編で触れたVeracodeの「2025 GenAI Code Security Report」を、ここでもう一度引きます。100以上のLLMに80種類の課題を解かせたところ、全体の45%でOWASP Top 10相当の脆弱性が入りました。種類別に見ると、XSS(CWE-80)は86%、ログインジェクション(CWE-117)は88%のケースで防げていません。しかも、新しいモデルでも安全性はほぼ横ばいでした。
AIは「エスケープが必要な場所」を高い確率で見落とす、ということです。文法的には正しく動くコードなので、本人(AI)も持ち主も気づきません。入力欄の確認は、人の目で、自分のアプリに対して、必ず一度はやっておく必要があります。
無害な確認方法
この章で使う確認方法は、すべて「普通の文字を入れてみて、普通に表示されるか」です。攻撃用の文字列を集めて試す必要はありませんし、やるべきでもありません。それは専門家が契約のもとで行う作業(ペネトレーションテスト)であり、自分のアプリであってもデータを壊すことがあります。
- 太字タグ。名前やメモなど、普通の文字だけを入れる欄に
<b>テスト</b>と入力して保存します。一覧や詳細画面で「テスト」が太字になったら、入力がHTMLとして解釈されています。普通の文字欄なら、エスケープ不足の印です。正しい状態は、<b>テスト</b>という文字がそのまま見えることです。ただし、太字や見出しを使える「リッチテキスト」の欄は、もともとHTMLを表示する設計なので、太字になるのは正常です。そうした欄の安全性は、危険なタグを取り除く処理(サニタイズ)があるかで決まり、この方法では確かめられません。また、ある画面で文字のまま表示されても、同じ値が出る別の場所(メール本文、管理画面、検索結果など)も安全とは限りません。この確認は「明らかな見落としを見つける」ためのもので、合格しても「XSS対策は完璧」という証明にはなりません。 - 極端に長い文字列。同じ文字を数千文字入れて保存します。画面が崩れる、エラー画面に内部情報(ファイル名やSQLの断片)が出る、保存に長時間かかる、のいずれかなら要対応です。
- 空、空白だけ、改行だけ。必須欄が空で通るか、空白だけで通るかを見ます。
- 全角数字、絵文字、記号。金額欄に「123」、名前欄に絵文字や「&」「'」「"」を入れます。壊れずに保存・表示されるか、あるいは丁寧に拒否されるかを見ます。
- ファイルアップロードがあるなら、許可する拡張子とサイズの上限が決まっているか、アップロードしたファイルが誰でも開けるURLに置かれていないかを見ます。
いずれも、入れるのは自分のテスト用アカウントのデータに対してだけです。結果は点検ノートに「入れたもの」「表示された結果」「問題の有無」を書きます。
このリポジトリで、利用者からの入力を受け取るすべての経路を列挙し、それぞれの安全性をレビューしてください。 対象:フォームの入力欄、URLのパラメータ、APIが受け取るデータ、ファイルアップロード、外部サービスから受け取るデータ。 それぞれについて、次を表にしてください。 1. 経路の名前とファイル名、行番号 2. その入力がデータベースへの命令に使われる場合、プレースホルダー付きのクエリ(パラメータ化)やORMを使っているか。SQLを文字列連結で組み立てている箇所があれば指摘 3. その入力が画面に表示される場合、フレームワークの標準のエスケープで表示しているか。HTMLをそのまま挿入する機能(dangerouslySetInnerHTML など)を使っている箇所があれば指摘 4. 長さ・形式・文字種の検証をサーバー側で行っているか 5. ファイルアップロードがある場合、拡張子・サイズ・保存先の制限 6. エラーが起きたとき、利用者の画面に内部情報(スタックトレース、SQL、ファイルパス)が出ないようになっているか 問題のある箇所を深刻な順に並べてください。 攻撃用の文字列の例は出力しないでください。 修正はまだしないでください。報告だけお願いします。
演習3:入力欄の安全確認
- 第8章の全体図から、入力欄のある画面をすべて点検ノートに書き出します。検索欄、ログイン欄、設定画面も忘れずに入れます。
- 上の定型文でAIにレビューさせ、「文字列連結」「HTMLをそのまま挿入」「検証なし」と指摘された箇所を点検ノートに写します。
- 自分のテスト用アカウントでログインし、書き出した入力欄のそれぞれに
<b>テスト</b>を入れて保存し、その値が表示される画面をすべて確かめます。普通の文字欄で太字になったものを記録します。リッチテキストの欄は「この方法では判定できない」と記録し、サニタイズの有無をAIのレビューで確かめます。 - 同じ欄に、数千文字の文字列、空白だけ、全角数字、絵文字を順に入れ、壊れずに保存・表示されるか、または丁寧に拒否されるかを記録します。
- エラーが出た場合、その画面に内部情報が出ていないかを見ます。出ていれば第12章の対象でもあります。
- ファイルアップロードがあれば、拡張子とサイズの制限、保存先のURLが誰でも開けるものでないかを確かめます。
- 記録した問題を「要対応」として点検ノートに残し、第13章で修正したあと、手順3から再確認します。
まとめ
- インジェクションもXSSも、入力した「文字」が「命令」として扱われる問題。論文では2位(199件、16.78%)。摘要欄の文字が会計システムの命令になってはいけないのと同じ。
- 守り方は2つ。データベースへは命令とデータを分けて渡す(プレースホルダー付きのクエリ)。画面に出すときはエスケープする(フレームワークの標準に任せ、HTMLをそのまま挿入する機能を避ける)。
- VeracodeによればAIはXSSを86%防げなかった。ここは人の目で、無害な文字列(太字タグ、長い文字列、全角数字)を自分のアプリに入れて確かめる。他人のサイトでは試さない。
出典
- OWASP Cheat Sheet Series「Cross Site Scripting Prevention Cheat Sheet」(OWASP)
- OWASP Cheat Sheet Series「SQL Injection Prevention Cheat Sheet」(OWASP)
- OWASP Top 10:2025(日本語版)A05 インジェクション(OWASP, 2025)
- IPA「安全なウェブサイトの作り方」(情報処理推進機構)
- Veracode「2025 GenAI Code Security Report」プレスリリース(Veracode, 2025年7月30日)
- Junquan Deng, Zhiyu Fan, Ruijie Meng「Understanding the (In)Security of Vibe-Coded Applications」(arXiv:2606.23130、2026年6月、v4は2026年9月14日)