SNSやブログの普及にともない、ユーザーが自由に文章を投稿してメッセージを表示させる機会が増えてきました。しかし投稿される文字列の内容によっては、セキュリティの観点で安全でない場合があります。
サーバーに送信された文字列を検査し、安全なものに変換することを「サニタイジング(エスケープ)」と言います。適切にサニタイジングを行わないと、「XSS(クロスサイトスクリプティング)」と呼ばれる攻撃の対象となり、様々な被害が発生する要因にもなります。
サニタイジング(エスケープ)とは具体的にはどのような処理なのでしょうか。今回はサニタイジング(エスケープ)の概要とその方法、さらにサニタイジングを適切に行わなかった時に、どのようなことが起きるのか詳しく解説します。
この記事の目次
サニタイジング(エスケープ)とは
サニタイジングとはHTMLとして意味のある文字を別の文字列に置き換える処理のことです。HTMLでは「<」や「>」の文字列がタグの一部としてブラウザに認識されます。これらを「<」や「>」といった文字列に置き換え、タグとしてではなく「<」や「>」とブラウザに表示されるだけの、ただ文字列にする処理がサニタイジングです。
上記例では「<」と「>」で囲まれた「script」タグをサニタイジングしています。サニタイジング処理する前ではscriptタグとして動作するHTMLタグですが、サニタイジング処理した後では「<」や「>」が「<」や「>」の文字列に置き換えられているため、ブラウザで表示した時にHTMLとしてではなく、ただの文字列として表示させることができます。
サニタイジング(エスケープ)がXSSに有効な理由
サニタイジングを行うことはXSS(クロスサイトスクリプティング)対策として有効であると言われています。これはなぜでしょうか。
XSS(クロスサイトスクリプティング)とはWebページに存在する脆弱性を悪用して、JavaScriptの不正なプログラムをWebページに仕込み、攻撃対象とは別のWebページに情報を流出させたりする脆弱性のことです。XSS(クロスサイトスクリプティング)については、当サイトの別記事で詳しく解説しているので、そちらもご覧ください。
サニタイジングがXSSに有効な理由は、入力フォームからWebページに送信されるデータの中にscriptタグがふくまれていても、サニタイジング処理によって「<」や「>」が「<」や「>」に置き換えられるため、scriptとして動作することを防げるからです。
もしタグが別の文字に置き換えられないと、Webページ上で不正なscriptが動作してしまい、思わぬ被害が発生する可能性があります。それではサニタイジングをしないと、どうなってしまうのでしょうか。これから詳しく解説します。
サニタイジング(エスケープ)をしていないとどうなるのか
適切にサニタイジングしていない場合、どのようなことが発生するのでしょうか。先ほども紹介したように、サニタイジングをしていないとXSS(クロスサイトスクリプティング)攻撃のターゲットとされることがあります。
XSS(クロスサイトスクリプティング)攻撃によって発生する脅威には以下ものがあげられます。
セッションハイジャック
Cookieにhttponly属性がついていない場合、JavaScriptのdocument.cookieを読み取ることで、攻撃者はCookieに含まれているセッション情報を盗み見ることができます。Cookieとは訪問者のパソコンに保存されている、小さなデータのことです。特定のWebサイトのログインに必要なログイン情報やセッション情報を保存するために使われています。
上記のコードは攻撃用サーバーに設置されているCGIへのパラメータとして、ユーザーのCookie情報を渡しているサンプルです。XSSの脆弱性があるWebページに上記のようなJavaScriptコードが記載されていることで、攻撃用サイトにユーザーのCookie情報が不正に送信されてしまいます。
入力フォームのタグを埋め込まれ個人情報不正窃取される
Webページに個人情報を不正窃取するための入力フォームを埋め込み、訪問者がその入力フォームに個人情報や機密情報を入力し、その情報を攻撃者に不正に送信されることがあります。
Webページに偽の情報を表示させる
不正に埋め込まれたJavaScriptによって、本来はWebページに表示されていない、偽の情報がWebページに表示される場合があります。
Webページ上で強制的に操作される
不正に埋め込まれたJavaScriptによって強制的にページ遷移などの操作が行われることがあります。
サニタイジング(エスケープ)の方法
HTMLにおけるサニタイジングの方法として「<」や「>」を「<」や「>」に置き換える方法を紹介しました。さらにPHPやJavaScriptのプログラミング言語におけるサニタイジング処理について紹介します。
PHPでのサニタイジング(エスケープ)の方法
PHPではhtmlspecialchars関数を使うことで、簡単にサニタイジング処理できます。例えばユーザーが入力フォームから送信した文字列を$str変数に格納されている場合は、以下のような使い方です。
htmlspecialchars関数の戻り値を$out変数に返却します。この$out変数にはサニタイジング済みの文字列が格納されている状態になります。この関数の第2引数には様々な定数を指定できます。一般的には「ENT_QUOTES」を指定することが多く、これにより「<」や「>」だけでなく、「’(シングルクオート)」や「”(ダブルクオート)」に対してもサニタイジングを行います。
JavaScriptでのサニタイジング(エスケープ)の方法
JavaScriptにはPHPにおけるhtmlspecialchars関数のようにサニタイジングを専用で行う組み込み関数はありませんが、文字列の置換を利用してサニタイジングを行うオリジナルの関数を定義して利用します。
上記の関数「htmlentities」では「<」や「>」だけでなく「”(ダブルクオート)」や「&」もそれぞれ別の文字列「"」や「&」に置換しています。これは「”(ダブルクオート)」や「&」もHTMLとして意味を持つ文字列であるため、サニタイジング処理でただの文字列として表示させるために必要だからです。
入力の段階でデータをチェックする方法もある
サニタイジングにより「<」や「>」などを「<」や「>」に変換して表示させる方法を紹介してきました。その他の方法として、ブラウザに入力されたデータをその場でチェックして、不正な文字列を保存しないようにすることも有効です。
例えば郵便番号を入力するフォームでは数字以外の文字を入力できなくする処理です。
入力されたデータのチェックはブラウザ上ではなく、サーバー上で行うことが重要です。ブラウザ上でのチェックはJavaScriptによるチェックとなりますが、ブラウザでJavaScriptを無効にすることで、ブラウザ上でのチェックは免れてしまうからです。XSS対策として入力値をチェックする場合は、PHPなどのサーバー側で動作する方法でチェックするようにしましょう。
まとめ
これまで紹介してきたように、サニタイジング(エスケープ)はXSS攻撃への対策として必要不可欠です。XSS攻撃のインターネットの黎明期から存在する攻撃手法ですが、現在でも様々なWebアプリケーションにおける脆弱性の一つとして報告されることがあります。
ブラウザから入力される文字列はいつも安全であるとは限りません。悪意のある攻撃者は公開されているWebアプリケーションの脆弱性を悪用することを常に考えています。
Webアプリケーションの開発の際には、入力される文字列が安全なものであると思い込まず、サニタイジング(エスケープ)が適切に実装されているか、しっかりとチェックを行うことが重要であると言えるでしょう。