ウェブサイト制作における脆弱性(セキュリティホール)と基本的対策 – クロスサイトスクリプティング脆弱性

危機管理
データセキュリティ

ウェブサイト制作を行う上で検討しないといけない点としてセキュリティ対策があります。

従来の静的なウェブサイトでは、ウェブサイト管理者が悪意でない限り問題とならなかったのですが、動的ウェブサイトでは脆弱性(セキュリティホール)が問題となります。

これはどういうことかと言いますと、良く知られた典型的なセキュリティ脆弱性の一つである「クロスサイトスプリクティング( XSS: Cross Site Scripting)」で説明したいと思います。

クロスサイトスプリクティング脆弱性とは?

クロスサイトスプリクティング脆弱性が問題となるのは掲示板サイト等です。

例えば、2ch(2ちゃんねる)という掲示板の書き込みを見ると、ハイパーリンクが張ってあることがあると思います。

「掲示板上の不明なリンクにはアクセスしないほうが良い」とか「メールを開いてリンクをアクセスしない」等とよく言われますが、それは悪意のある第3者がクロスサイトスプリクティング脆弱性を利用し、情報を盗もうとしている可能性があるからにほかなりません。

このような掲示板のようなウェブアプリケーションは、HTTP(HyperText Transfer Protocol)という、サーバとクライアント間において決まったプロトコル(手続き)を介し、エンドユーザーが入力したデータ(書き込み内容)をウェブサイト側で受け取り、さらに、ウェブサイト側は、受け取ったデータをHTTPプロトコルを介してブラウザに表示する、という処理になります。

この時、ウェブサイト側が、エンドユーザーから受け取った書き込みデータをそのままの状態でブラウザ上に表示させてしまうと問題なんです。

何故かと言うと、書き込まれたデータにHTMLコードやスクリプトコード等のタグが含まれていると、そのままデータをブラウザに渡すと、ブラウザはHTMLタグやスクリプトタグだと認識してしまう事から、掲示板上にリンクが張れてしまうのです。

そして、外見上はどこかのウェブサイトへのリンクのように見えても、実は有害なスクリプトが仕込まれているというわけです。

クロスサイトスプリクティング脆弱性対策として – サニタイズ処理

サニタイズ

このように、外部エンドユーザからの入力などによって生成されるページでは、ウェブサイト側は対策を講じる必要があり、最も良いのは、ウェブサイト側が受け取った書き込みデータからタグはあらかじめ除去しておくとか、タグ自体を文字列に変換する等の文字列処理を施してブラウザに渡すとか、データを無害化してブラウザに出力する事です。

これをサニタイズ処理と言います。

動的ウェブサイトを構築する際のコンピューター言語にPHP言語(ワードプレスもPHP言語で作られたソフトウェアです)がありますが、PHP言語にはあらかじめ、このサニタイズ処理のための文字列関数としては、htmlspecialchars()が用意されています。

・htmlspecialchars()関数

この関数は、<(小なり)や、>(大なり)、"(ダブルクォート)、'(シングルクォート)等の特殊記号をHTMLエンティティという&で始まり;で終わる文字列に変換してくれる関数です。

このHTMLエンティティ化された文字列をブラウザに渡すと、タグを文字列として表示してくれます。

ワードプレスではデフォルトAPIを使うにおいてはサニタイズ不要

ワードプレスはPHP言語で作られたソフトウェアです。ワードプレスにおいてウェブサイト制作するにおいては、ワードプレスにより準備されたサニタイズ用関数もあります。

[入力値サニタイズ用関数]

関数名説明
sanitize_email()メールアドレスとして不適当な文字を除去
sanitize_file_name()ファイル名として不適当な文字を除去し、スペースをダッシュに変換
sanitize_html_class()HTMLのクラス名として不適当な文字を除去
sanitize_key()識別子として不適当な文字を除去
sanitize_text_field()ユーザーが入力した文字列を無害化する
sanitize_title()タイトルとして不適当な文字を除去
sanitize_user()ユーザー名として不適当な文字を除去
esc_url_raw()データベースに渡すURLとして不適当な文字を除去

ワードプレスにおいて、上記のように入力値のサニタイズ関数が用意されてはいますが、実はあまり考える必要はありません。ワードプレスにおいて入力値を保存する際には、一般的にワードプレスAPIが用いられますが、これらAPI関数の中で適切にサニタイズされているからです。

出力値においてもワードプレスにはthe_title()やthe_content()等のテンプレートタグ関数を使うことが多いかと思います。これらテンプレートタグに該当する関数も内部で適切にサニタイズされていますので問題はありません。

//テンプレートタグを使って画面に出力する場合はサニタイズ不要
<h1><? php the_title(); ?></h1>

ただし、テンプレートタグを使わずにHTML要素内のテキストはすべて、下記のようなesc_html()関数等でのサニタイズが必要です。

//出力値にサニタイズが必要な例
<h1><? php echo esc_html($title); ?></h1>

基本的な考え方としては、むやみにechoは使わずに、なるべくテンプレート タグ の 使用 を 考えたほうが良いです。

他にも、

・aタグのhref属性や、imgタグのsrc属性等、画面に表示するURLはすべて、下記のようなesc_url()関数でサニタイズ

<img src="<? php echo esc_url($url); ?>">

・インラインのJavaScriptでは、すべてesc_js()関数でサニタイズ

<a href="#" onclick="<? php echo esc_js($script); ?>">クリックしてください</a>

・HTMLタグのその他属性は、すべてesc_attr()関数でサニタイズ

<ul class="<? php esc_attr($nav_class); ?>">
<input type="text" name="example" value="<? php echo esc_attr($value); ?>">

クロスサイトスクリプティング以外の脆弱性

典型的な脆弱性の例としてクロスサイトスクリプティングを取り上げましたが、他にも、

  • SQLインジェクション
  • クロスサイトリクエストフォージェリ
  • パストラバーサル
  • NULLバイト攻撃
  • メールヘッダインジェクション 他

等があります。

しかし、一般的なホームページ制作において知っておくべきなのはクロスサイトスクリプティングだと思います。