Webセキュリティを学ぶ中で、「サニタイズ」と「エスケープ」という2つの言葉が似たような文脈で使われることがあり、混同してしまう方も多いでしょう。
しかし、サニタイズ(sanitize)とエスケープ(escape)は、目的・処理の方向性・適用タイミングにおいて明確な違いがあります。
本記事では、サニタイズとエスケープそれぞれの定義と特徴を整理し、具体的な違いと使い分け、そして両者を組み合わせた安全な実装方法について詳しく解説していきます。
サニタイズとエスケープの基本的な違い
それではまず、サニタイズとエスケープの基本的な定義と、両者の本質的な違いについて解説していきます。
サニタイズの定義と目的
サニタイズは、入力データから危険な要素を除去・変換・無害化する処理です。
主に入力段階で行われ、不正なHTMLタグの削除、禁止文字の除去、入力値の正規化などが含まれます。
サニタイズは「危険なものを取り除いて安全なデータにする」という方向性の処理です。
たとえば、リッチテキストエディターの入力からscriptタグを除去する処理がサニタイズにあたります。
エスケープの定義と目的
エスケープは、データを出力する際に特殊文字を別の表現に置き換える処理です。
データ自体を変えるのではなく、特定のコンテキスト(HTMLやSQL・JavaScript等)で特別な意味を持つ文字を、そのコンテキストで無害な表現に変換します。
エスケープは「データの意味は保ちながら、安全に出力できる形式に変換する」という方向性の処理です。
たとえば、「<」を「<」に変換するHTML出力エスケープがその典型例です。
サニタイズは「危険な要素を除去する入力側の処理」、エスケープは「特殊文字を安全な表現に変換する出力側の処理」です。両者は処理の方向と目的が異なります。
処理のタイミングと方向性の違い
サニタイズとエスケープの最も重要な違いは、処理のタイミング(入力vs出力)にあります。
| 比較項目 | サニタイズ | エスケープ |
|---|---|---|
| 処理タイミング | 入力受け取り時 | 出力時 |
| 処理の方向 | 危険要素の除去 | 特殊文字の変換 |
| データへの影響 | データが変化する場合がある | 表現形式のみが変化 |
| 元データへの復元 | 除去された場合は不可 | 逆変換で元に戻せる |
| 主な目的 | 不正データの無害化 | コンテキスト別の安全出力 |
サニタイズの具体的な処理例
続いては、サニタイズの具体的な処理例をいくつか確認していきましょう。
HTMLタグの除去サニタイズ
ユーザーのコメントや入力テキストからHTMLタグをすべて除去する処理は、典型的なサニタイズの例です。
HTMLタグ除去のサニタイズ例(Python)
import re
def strip_html(text):
return re.sub(r'<[^>]+>’, ”, text)
user_input = “<b>Hello</b> <script>alert(‘XSS’)</script>”
result = strip_html(user_input)
→ “Hello alert(‘XSS’)”(タグが除去され、テキストのみ残る)
ただし、この単純な正規表現アプローチは完全ではなく、実際にはDOMPurifyやbleachなどの専用ライブラリを使うことが推奨されます。
入力値の正規化サニタイズ
フォーム入力の正規化も重要なサニタイズ処理です。
電話番号フィールドから数字以外の文字を除去する処理、メールアドレスを小文字に統一する処理、前後の空白(スペース)を除去するトリム処理などがこれにあたります。
これらは直接的なセキュリティ対策というよりも、データの品質を保つためのサニタイズです。
ファイルアップロード時のサニタイズ
ファイルアップロードにおけるサニタイズも重要な実装です。
ファイル名から「../」や特殊文字を除去し、安全なファイル名に変換する処理や、許可された拡張子以外のファイルを拒否する処理がサニタイズにあたります。
また、画像として送られてきたファイルに実際に画像データが含まれているかを検証することも、より厳密なサニタイズの一形態です。
エスケープの具体的な処理例
続いては、エスケープの具体的な処理例を各コンテキストで確認していきましょう。
HTMLエスケープの実例
最も一般的なエスケープが、HTML出力時のエスケープです。
HTMLエスケープの変換ルール
& → &
< → <
> → >
” → "
‘ → ' または '
元の文字列:Tom & Jerry <br>
エスケープ後:Tom & Jerry <br>
エスケープ後でも、ブラウザは「&」を「&」として正しく表示するため、ユーザーには元の文字列が表示されます。
エスケープはデータの「表示」は保ちながら「コードとしての実行」を防ぐ処理と言えるでしょう。
URLエスケープ(パーセントエンコーディング)
URLに含める文字列のエスケープは、パーセントエンコーディング(URLエンコード)として知られています。
日本語文字や特殊文字をURLで安全に扱うために、「%XX」形式に変換します。
URLエスケープの例
「東京」→ %E6%9D%B1%E4%BA%AC
「&」→ %26
「 」(スペース)→ %20 または +
SQLエスケープとその限界
SQLのエスケープは、シングルクォートなどのSQL特殊文字を無害化する処理です。
ただし、SQLエスケープは完全な対策にはならない場合があるため、必ずプリペアドステートメントと組み合わせて使用することが推奨されます。
エスケープ関数のみに頼った実装では、文字コードの違いやマルチバイト文字を利用した攻撃に対して脆弱になるケースがあります。
サニタイズとエスケープを組み合わせたセキュア実装
続いては、サニタイズとエスケープを適切に組み合わせた安全な実装方針について確認していきましょう。
多重防御の設計思想
セキュリティの設計原則として、多重防御(Defense in Depth)が重要です。
入力時のバリデーション(検証)・サニタイズを第一層、アプリケーション内部での型付き変数管理を第二層、出力時のコンテキストエスケープを第三層として多重に防御することが理想的です。
どれか一層だけに依存した実装ではなく、複数の防御層を組み合わせることで、一つの対策が漏れても他の層がカバーできる堅牢なシステムが実現できます。
フレームワークの自動エスケープ機能の活用
モダンなWebフレームワークの多くは、テンプレートエンジンによる自動HTMLエスケープ機能を提供しています。
Djangoのテンプレートエンジン、Jinja2、React(JSX)、Blazerなどは、変数をHTMLに埋め込む際に自動でエスケープします。
この自動エスケープを意図的に無効化する「safe」マーカーや「dangerouslySetInnerHTML」などを使う場合は、そのデータが確実にサニタイズ済みであることを確認してから使用しましょう。
コードレビューでの確認ポイント
サニタイズとエスケープが正しく実装されているかをコードレビューで確認する際のポイントをまとめます。
まず、すべてのユーザー入力がバリデーション済みかどうかを確認します。
次に、HTMLへの出力時に自動または手動エスケープが行われているかをチェックします。
データベース操作はプリペアドステートメントを使っているか、生のSQL文字列結合が使われていないかも確認が必要です。
また、ファイルパスの操作でパストラバーサル対策が施されているかどうかも重要なチェック項目となります。
まとめ
本記事では、サニタイズとエスケープの基本的な違い、それぞれの具体的な処理例、そして両者を組み合わせた多重防御の実装方針について解説しました。
サニタイズは「入力時に危険な要素を除去する処理」、エスケープは「出力時に特殊文字を安全な表現に変換する処理」という明確な役割の違いがあります。
両者は対立するものではなく、組み合わせて使うことで最大の効果を発揮するセキュリティ対策です。
Webアプリケーション開発において、サニタイズとエスケープの正しい理解と実践は、安全なサービスを提供し続けるための基盤となるでしょう。