JavaScriptのXSS対策でエスケープ処理を行う方法を現役エンジニアが解説【初心者向け】
初心者向けにJavaScriptでXSS対策のためのエスケープ処理が行える関数について解説しています。XSSはサイバー攻撃のひとつで、不正なスクリプトが実行されるものです。エスケープ処理による対策方法を見ていきましょう。
テックアカデミーマガジンは受講者数No.1のプログラミングスクール「テックアカデミー」が運営。初心者向けにプロが解説した記事を公開中。現役エンジニアの方はこちらをご覧ください。 ※ アンケートモニター提供元:GMOリサーチ株式会社 調査期間:2021年8月12日~8月16日 調査対象:2020年8月以降にプログラミングスクールを受講した18~80歳の男女1,000名 調査手法:インターネット調査
監修してくれたメンター
永井浩平
バックエンド、フロント、クラウドなど幅広く業務を行う。
テックアカデミーでは、フロントエンドコース / Javaコースのメンター。
JavaScriptのXSS対策でエスケープ処理を行う方法について、テックアカデミーのメンター(現役エンジニア)が実際のコードを使用して初心者向けに解説します。
目次
そもそもJavaScriptについてよく分からないという方は、JavaScriptとは何なのかについて解説した記事を読むとさらに理解が深まるでしょう。
はじめに
今回はWebサイトのセキュリティに関する内容です。
近年、運用や設定ミスなどによる個人情報の流出の他に、悪意のあるWebサイトへの攻撃によるセキュリティ事故が多く発生しています。
企業の信頼失墜や損害などを防ぐために、Webのセキュリティ対応は必須です。
今回はアプリケーションの脆弱性をついた、XSS(クロスサイトスクリプティング)攻撃を行えないようにする実装方法について説明します。
ぜひ最後まで内容を確認してくださいね。
XSSとは
XSS(クロスサイトスクリプティング)とは、WebアプリケーションやWebサイトへの攻撃方法の1つです。
該当のページなどに、スクリプトを埋め込み実行するというものです。
悪意のあるスクリプトが実行されると、偽の情報を表示されたり、情報が抜き取られたりするような被害が出る可能性があります。
ここで、XSSの対策がされていないサイトで、攻撃が行われた例を1つみていきましょう。
以下、掲示板やチャットのような、投稿内容を他の人が閲覧できるサイトだとします。
<html> <head> </head> <body> <textarea id = "inputArea" rows="4" cols="40"></textarea> <input type="button" id ="btnDo" value="投稿"></input> <div id="result"></div> </body> </html>
const btnDo = document.getElementById('btnDo'); const result =document.getElementById('result'); const inputArea =document.getElementById('inputArea'); btnDo.addEventListener('click', function() {//投稿ボタンクリック時 result.innerHTML = inputArea.value; //入力欄の内容をHTMLとして表示 });
こちらは入力欄の内容を投稿ボタンをクリックすることで、下部のinnerHTMLプロパティに代入してブラウザに表示します。
入力欄に以下の文字列を設定して、再度投稿ボタンを押してみましょう。
<input type="button" value="戻る" onclick="location.href='https://techacademy.jp/'"></input>
すると、クリックボタンが追加されることが確認できたと思います。
上記のように、Webサイトのパーツに偽装したコンテンツを表示できました。
こちらは他のユーザーが決算などの情報を入力した後に、クリックやホバーの動作で特定のスクリプトを実行させ、入力した情報を別のサーバに送信することで、画面表示項目などを盗み取ることができます。
またscriptタグを埋め込むことで、ブラウザ表示のタイミングでcookieの情報などを読み取り、外部へ送信できてしまいます。
現在はブラウザのセキュリティ対応で対策されていますが、URLに含まれるクエリパラメータなどに不正なスクリプトを埋め込んで、遷移先のページにスクリプトを埋め込んだり、偽装したHTML要素を表示する攻撃もあります。
XSS対策のためのエスケープ処理が行える関数
XSSの対策は、HTMLでタグや区切りに使われる下記の表の5つの記号を無効化することです。
この5つの記号は、HTMLにおいて要素や値の区切りなどの文法上で意味のある特殊文字となっています。
無効化するには、その記号を表す特殊なコードにエスケープしましょう。
これは、文字を置換するということです。
表の左側が無効化する記号、右側が置き換える文字コードです。
< |
< |
> |
> |
& |
& |
“ |
" |
‘ |
' |
この文字の置換処理のタイミングはデータを受け取った時ではなく、HTMLの生成時に行うことが推奨されています。
画面に表示する直前に行うとイメージするとよいでしょう。
直前に行うことで、複数のデータをそのまま同じように扱うことができ、2重に置換してデータの意味が変わってしまうエラーも防げます。
JavaScriptの文字列の置換は、文字列を表すStringオブジェクトのreplaceメソッドで可能です。
実際に使ってみよう
JavaScriptでXSS対策のために5つの記号をエスケープ(置換)する関数を作成してみましょう。
innerHTMLのようなHTMLを生成する処理がある場合は、この関数を呼び出して置換された文字列を使えば安全です。
function escapeHTML(string){ return string.replace(/&/g, '<') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, "'"); }
replaceメソッドで5つの記号をコードに置き換えています。
コードに置き換えられているため、画面に記号は表示されます。
それでは今回の最初に説明したHTMLを使い、関数で置換した文字列の表示を確認してみましょう。
const btnDo = document.getElementById('btnDo'); const result =document.getElementById('result'); const inputArea =document.getElementById('inputArea'); btnDo.addEventListener('click', function() {//投稿ボタンクリック時 result.innerHTML = escapeHTML(inputArea.value); //入力欄の内容をHTMLとして表示 });
以下のようにタブではなく、文字列として表示されるため、不正なスクリプトの実行やオブジェクトの表示を防げます。
また<>など、ユーザーが入力した場合も表示できます。
ブラウザの識別する特殊な記号などを、意味を持たない文字に置き換えることをサニタイジングと呼びます。
まとめ
今回はXSSとその対策を紹介しました。
フロントエンドに関連する脆弱性は、以下一例ですが他にも様々な攻撃方法が確認されています。
・XSSと同様に不正なHTMLタグを透過させて表示して、情報を盗み取るクリックジャギング攻撃
・cookieなどの情報を悪用したCSRF(クロスサイトリクエストフォージェリ)
フロントエンドやバックエンド、Webサーバともに攻撃手段の対策を行うことも大切ですが、ライブラリやOSなどを最新の状態に保つこともセキュリティ対策で重要な考えです。
また、対策やガイドラインが独立行政法人情報処理推進機構(IPA)で日々更新されているため、セキュリティについて興味がある方はIPAのサイトも定期的に閲覧しましょう。
テックアカデミーでは、初心者でもJavaScript・jQueryを使ったWebサービス公開を習得できるオンラインブートキャンプJavaScript/jQuery講座を開催しています。
挫折しない学習方法を知れる説明動画や現役エンジニアとのビデオ通話とチャットサポート、学習用カリキュラムを体験できる無料体験も実施しているので、ぜひ参加してみてください。