【比較】バリデーションとサニタイズの違い¶
概要¶
「バリデーション(Validation/入力検証)」と「サニタイズ(Sanitization/無害化)」は、どちらも信頼できない入力を扱う安全対策ですが、入力に対する“態度”が正反対です。バリデーションはルールに照らして入力を受理するか拒否するかを判定するだけで、原則として入力値を書き換えません。サニタイズは出力先(シンク)に合わせて危険な文字をエスケープ・除去・変換して無害化する操作で、データを書き換えます。
両者は混同されやすく、「とりあえずサニタイズしたから安全」「バリデーションすればSQLインジェクションは防げる」といった誤った設計につながりがちです。本記事では OWASP Cheat Sheet Series を一次情報として、検証=門番、無害化=出力文脈ごとの加工、という線引きを正確に整理します。
例えるなら:空港のセキュリティ¶
バリデーションは「保安検査ゲート」です。規定に合わない手荷物はそのまま突き返すだけで、中身を作り変えはしません。サニタイズは「危険物を回収・無力化する処理」で、ライターやハサミを取り除いてから先へ通します。そして「機内で液体を出す(出力する文脈)」「貨物室に積む(別の文脈)」で扱いが変わるように、サニタイズ/エンコードは“出力先ごと”に方法を変える必要があります。
詳細比較¶
| 項目 | バリデーション (Validation) | サニタイズ/出力エンコード (Sanitization / Output Encoding) |
|---|---|---|
| 目的 | 入力が仕様・型・範囲・形式を満たすか判定 | 出力先(シンク)でコードと解釈されないよう無害化 |
| 入力への作用 | 原則書き換えない(受理 or 拒否) | 書き換える(エスケープ・除去・変換) |
| 判定方針 | 許可リスト(allowlist)が原則。拒否リストは回避が容易で「重大に欠陥のあるアプローチ」と OWASP が明言 | 出力文脈に応じた変換ルール(HTML/JS/CSS/URL/SQL で異なる;SQL はエスケープではなくパラメータ化クエリが原則) |
| 適用タイミング | 入力の受け取り直後(境界) | 多くは出力の直前(どのシンクへ出すかが決まる時点) |
| 文脈依存 | 構文(syntactic)+意味(semantic)の両面で検証 | 出力文脈ごとに方法が変わる(HTML本文/属性/JavaScript/CSS/URL) |
| 単独で攻撃を防げるか | 不可。OWASP は「XSSやSQLiの主たる防御に使うべきでない」と明記(影響低減には寄与) | XSSの主防御は文脈別の出力エンコード。SQLiの主防御はプレースホルダ(パラメータ化クエリ) |
| 代表的な実装例 | 型/長さ/正規表現/列挙、ビジネスルール検証 | HTMLエンティティ化、JS文字列エスケープ、URLエンコード、HTMLサニタイザ(例: DOMPurify) |
OWASP は入力検証の目的を「整形済みの正しいデータだけをワークフローに通し、不正データが DB に残らないようにすること」と位置づけつつ、「入力検証は XSS や SQL インジェクション等を防ぐ主たる手段にすべきではない(正しく実装すれば影響低減には大きく寄与する)」と明記しています。XSS の主防御は出力文脈ごとのエンコードであり、ブラウザは HTML・JavaScript・URL・CSS を別々に解釈するため「誤ったエンコード方式の使用は脆弱性や機能不全を招く」とされています。
よくある誤解¶
-
「サニタイズしてから使えば、その後は信頼してよい」は誤り(sanitize-then-trust アンチパターン)。 無害化は“どのシンクに出すか”に強く依存します。HTML本文向けにエスケープした文字列を、後で JavaScript 文字列や URL や SQL に流用すれば、その文脈では無害化されておらず脆弱なままです。OWASP も「サニタイズ済みコンテンツをその後さらに改変してはならない(保護を損なう)」と注意しています。無害化は“出力直前に、その文脈用に”行うのが原則です。
-
「入力をバリデーション(あるいはエスケープ)すればSQLインジェクションは防げる」は誤り。 SQL インジェクションの主たる防御はパラメータ化クエリ(プリペアドステートメント)であり、入力検証や手動エスケープはその代替になりません。OWASP は入力検証を「XSSやSQLiの主防御にすべきでない」と明言しています。検証は多層防御の補助であって、安全なクエリ構築の代わりにはなりません。
-
「バリデーションとサニタイズは同じ(どちらも“入力をきれいにする”)」は誤り。 バリデーションは合否を判定して拒否するもので、原則として値を書き換えません。サニタイズは値を書き換えて無害化するものです。両者を「入力浄化」と一括りにすると、「拒否すべき不正値を勝手に整形して通してしまう」「出力文脈を無視した一括サニタイズで保護漏れ/機能破壊が起きる」といった事故を招きます。
-
「拒否リスト(ブラックリスト)で危険文字を弾けば十分」は誤り。 OWASP は拒否リスト方式を「攻撃者が回避するのが容易な、重大に欠陥のあるアプローチ」とし、ユーザー入力には許可リスト(allowlist)検証を推奨しています。「
<script>を弾く」式の対策は容易にバイパスされます。
実務での選び分け¶
- 入力が仕様(型・長さ・範囲・形式・ビジネスルール)を満たすか確かめたい → バリデーション。境界で許可リスト方式により実施し、構文と意味の両面を見る。不正なら受理しない(書き換えない)。
- HTMLページにユーザー入力を表示する → 出力する文脈ごとのエンコード(HTML本文/属性/JS/URL)。XSSの主防御。
- ユーザーにリッチHTML(WYSIWYG等)の投稿を許す必要がある → エンコードでは機能が壊れるため、DOMPurify 等の HTML サニタイザで安全な部分集合に限定する。
- DBへクエリを発行する → 値の連結ではなくパラメータ化クエリ(プリペアドステートメント)。バリデーション/エスケープを代替にしない。
- 設計の基本姿勢 → バリデーション・サニタイズ・出力エンコード・パラメータ化を“どれか一つ”ではなく多層で重ねる。
ひとことまとめ¶
バリデーションは「ルール違反の入力を拒否する門番(書き換えない)」、サニタイズ/出力エンコードは「出力先の文脈に合わせて無害化する加工(書き換える)」であり、どちらも単独では注入攻撃の主防御にならず、パラメータ化クエリや文脈別エンコードと多層で組み合わせるのが原則です。
出典・参考¶
- Input Validation Cheat Sheet — OWASP Cheat Sheet Series — 入力検証の目的、許可リスト推奨/拒否リスト批判、構文・意味の検証、主防御にすべきでない旨
- Cross Site Scripting Prevention Cheat Sheet — OWASP — 文脈別出力エンコードが主防御、HTMLサニタイザ(DOMPurify)の位置づけ
- SQL Injection Prevention Cheat Sheet — OWASP — SQLi の第一防御はパラメータ化クエリ(検証/エスケープは代替でない)