Web制作、Web開発の歩き方

JavaScriptのきほんを学ぼう

■第9話:JavaScriptのサニタイジング

(最終更新日:2024.03.23)

JavaScriptの猫
この記事は5分で読めます!
(絵が小さい場合はスマホを横に)

「XSSを防ぎ安全にサイトを運用したい!」

クロスサイトスクリプティング(XSS)は、Webサイトに悪意のあるスクリプトを埋め込み、攻撃する手法である。 XSSを予防するには、JavaScriptで特殊文字を表示させないようにサニタイジングすることが重要である。 もし悪意のあるコードがそのまま表示されてしまうと、Cookieの中の機密情報を盗まれたり、Webサイトを改ざんされる恐れがある。 今回はそんなJavaScriptを利用した不正な手続き、XSSを防ぐ方法であるサニタイジングについて説明する。


1. クロスサイトスクリプティング(XSS)とは

XSSとは、Webサイトに悪意のあるスクリプトを埋め込み、攻撃する手法である。 XSSは、HTMLのtextboxやinputに対して悪意のあるスクリプトを入力し、それが実行されると実害が生じる。 例えば、Webサイトの掲示板や質問箱で、下記のような「scriptタグと悪意のある命令」を書き込み、 送信してそのまま質問のログとして出力されてしまうと、そのページにアクセスした人のcookie(個人情報)が盗まれてしまう。 もしくは、window.locationなどの命令で悪意のあるサイトに転送することもできてしまう。 このような不正なスクリプトを実行させない処理がXSSである。

三項演算子の使い方

XSSの例

2. JavaScriptのサニタイジング

PHPを使用している場合は、入力した情報を表示するときにhtmlspecialchars関数を用いれば、外部から入力された不正なスクリプトを無効化してくれる。 また、Laravelのようなフレームワークをフロントサイドで用いれば、文字列を呼び出した際、そのような処理を自動で実行してくれる。 このように、HTMLとして表示する際にscriptを実行させずに無害化するのが、サニタイジングである。 最近のフレームワークを使う場合は、サニタイジングは標準で実装されているのでその点は安心してほしい。

ただし、Svelteなどのフロントエンドフレームワークで、テンプレートリテラルの中でHTMLを組み立てる場合、注意が必要だ。 (テンプレートリテラルの使い方に関しては、第4話の図4-1を見てほしい。) Svelteでは、テンプレートリテラル中でHTMLを使う場合、「{@html 〇〇}」という記法を用いてサニタイズを無効化して使う。 そうしないと、HTML要素(<div></div>など)を含んだ変数がタグとして認識されないからだ。 実際、悪意のあるコードをデータとして忍ばせると、下記のように「test」を表示するalertが実行できてしまう。

XSSを混入させる

テンプレートリテラル中でXSSを実行する

このような攻撃を外部から受けないためには、そもそもテンプレートリテラル中でユーザーの入力をできなくするか、 自作の関数を用いてサニタイズする必要がある。自作の関数でサニタイズする例を次に記す。

外部情報から悪意のあるスクリプトを実行させないようにするには、 「&,<,>,",',`」の6つの特殊文字をただの文字列として表示するように置換すれば良い。 下記に置換するための自作の関数を記す。これで、悪意のあるJavaScriptの命令は実行されなくなる。

JavaScriptのサニタイジング

JavaScriptで取得した情報をサニタイズする自作の関数


3. その他の予防方法

JavaScriptのXSS対策以外にもXSSを予防する措置を2点挙げる。 一つはinputで入力させる際、入力値を制限するということだ。 ただし、ブラウザの機能でJavaScriptを無効化したり、開発者ツールでHTML自体を編集できるため、悪知恵の働く人には通用しない。 ただし、ある程度の防止効果はあるだろう。

次に考えられるのは、重要な情報をJavaScriptで取得できなくすることだ。 セッション等の重要なデータの保管にcookieを使うにしてもHttpOnlyを使えば、JavaScriptからその情報にアクセスすることはできなくなる。

そして、もう一つはWAF(Web Application Firewall)を用いるということだ。 Webページの不審なリクエストを監視するツールで、不審なサイトへの送信があればそれを遮断し、被害が広がるのを防ぐということは可能だろう。

WAFによるWebページ監視と遮断のイメージ

4. まとめ

従来のフロントエンドとバックエンドを分けない手法であれば、フレームワーク自体にサーバー側で保護する仕組みがあったため、 自分で実装しなくても不正な入力を自動的に保護していた。 しかし、今はバックエンドとフロントエンドを分けて、REST APIで通信する方法が主流である。 今回のようにフロントエンドでも、セキュリティ対策をしっかり行う必要がある。 まずは、今回紹介したサニタイジングをしっかり実装できるようにしよう。XSS対策に関しては自信を持てるはずだ。


▼参考図書、サイト

クロスサイトスクリプティング(XSS)とは?わかりやすく解説  攻撃遮断くん
JavaScriptで特殊文字エスケープする3つの方法  PisukeCode
Svelteチュートリアル  Svelte公式サイト