入力の検証(バリデーション)— 外から来た値を疑う

中級の解説は準備中のため、中級の内容を表示しています。

概要 — まず全体をつかむ

初級では「外から来た値を、そのまま使わずに確かめる」を土台としました。中級では、何を・どこで・どの順で確かめるかを整理します。

詳細 — 1段階ずつ追う

なぜ必要?

ブラウザから届く値・URLのパラメータ・アップロードファイル・APIのリクエストボディ——これらはすべて信頼境界の外から来ます。攻撃者が自由に作れる以上、そのまま処理へ流すと XSS や SQLインジェクションの入口になります。

ポイントは、検証は信頼境界を越える所で行うこと。外の値が内側のロジックへ入る手前に「関所」を置きます。

どう確かめる?

検証の観点を、緩い順ではなく絞り込む順に重ねます。

  1. — 数値・真偽・日付など、期待する型か
  2. 長さ — 上限・下限。極端に長い入力はそれ自体が攻撃の兆候
  3. 範囲 — 数値や日付が想定の区間に収まるか
  4. 形式 — メール・電話・IDなど、決まった形に合うか
  5. 許可リスト > 拒否リスト — 最後は「通してよいものだけ通す」に寄せる
アニメーション『入力検証=関所』を開く
外から来た値(信用しない)フォーム利用者の入力URLパラメータAPI外部からの呼び出し⛩ 関所(検証)型が正しい?範囲内?許可リストにある?通ったものだけ処理へ安全な値だけを使う✕ 怪しいものは弾く(拒否)フロントのチェックは「親切」。サーバで必ず再検証する。外から来たものは信用しない。すべての守りの土台。

正規化を先に、検証を後に。 全角/半角、大文字/小文字、Unicodeの合成形などの表記ゆれを揃えてから検証します。順序を逆にすると、検証後に別の形へ化けて許可リストをすり抜けられます。

そして最重要は、サーバ側で必ずやること。フロントの検証は UX 補助(入力ミスへの親切)であって、防御ではありません。攻撃者はフロントを無視して直接サーバへ送れます。

登場人物メモ:

  • ※1 信頼境界 — 信用できる領域と、できない領域の境目。検証はこの境界で行う
  • ※2 正規化 — 表記ゆれを揃え、比較・検証できる形にそろえる前処理

検証と無害化は別物

検証(入口)出力エスケープ(出口) は役割が違います。

  • 検証 — 想定外の値を「弾く」。入口の関所
  • 出力エスケープ — 通した値を、出す先(HTML・SQL・URL)で「無害化」する。出口の変換

検証を通った値でも、出力の文脈しだいで危険になります。だから両方が必要で、片方では守れません。

⚠️ 破れ方のパターン

  • フロントだけで検証 — 直接サーバへ送られたら素通り。サーバで必ず再検証
  • 拒否リスト頼み — 危ないものを列挙する方式は抜けが出る。許可リストへ寄せる
  • 正規化忘れ・順序ミス — 検証後に化ける表記ゆれをすり抜けられる
  • 検証と無害化の混同 — 入口の検証だけで安心し、出口のエスケープを省く

理解度チェック

そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。

1. 入力の「正規化」と「検証」の順序で正しいのは?

2. 入力検証の「観点」の並べ方として、より安全側なのは?

3. 検証で「極端に長い入力」を弾くべきだと本文が述べる理由はどれ?

4. フロント(ブラウザ)側の入力検証の位置づけとして本文が述べるのはどれ?

5. 入口の「検証」と出口の「出力エスケープ」の関係として正しいのはどれ?

6. 次のうち「信頼境界の外から来る値」に当たらないのはどれ?

7. 検証を行う、信用できる領域と信用できない領域の境目を何と呼ぶ?

8. 全角と半角・大文字と小文字・Unicodeの合成形などの表記ゆれを揃え、検証できる形にそろえる前処理を何と呼ぶ?