画像ツール一覧

XSS

Cross-Site Scripting

セキュリティと認証

Webページの処理の不備によって、攻撃者のスクリプトが閲覧者のブラウザ上で、そのサイトの権限で実行される脆弱性や攻撃です。画面の書き換えや、利用者に代わる操作などにつながります。

🐾 猫で例えると?

先に入ってくつろいでいた茶トラのスペースに、後からアメショが無理やり体をねじ込んできて窮屈そうに圧迫されている様子
正規の領域に予期せぬ外部要素が強引に注入された状況

特等席にいた茶トラの隙間へアメショが割り込む姿を、画面の正規の内容へ別のものが入り込む例えにします。XSSで重要なのは窮屈さや処理の重さではなく、「表示するだけのデータ」が「実行する命令」として扱われることです。

🐾 PR

💻 セキュリティにおける「XSS」とは?

XSSは、信頼できない値をHTMLやスクリプト等の実行につながる場所へ安全でない方法で渡すと起こり得ます。サーバーの出力だけでなく、ブラウザ内でURLなどを読み、ページの要素をプログラムから扱う仕組みであるDOMを書き換える処理も確認します。

実行されたコードは、そのページで利用者ができる操作を悪用する場合があります。HttpOnlyのCookieはJavaScriptから読めませんが、Cookieを読めなくても認証済みの要求を送ったり、入力を盗み見たりする危険は残ります。

⚠️ XSSの仕組みと種類

XSSは、その攻撃コードがどこを経由してどのように実行されるかによって、大きく3つのタイプに分類されます。それぞれの特性に合わせた多層防御が必要です。

XSSの3大分類

格納型は保存された内容が表示時に実行されるもの、反射型は要求に含まれた値が応答へ返されて実行されるものです。DOM-basedはブラウザ側のDOM操作に原因がある分類で、格納・反射という区分と重なる場合もあります。影響の大きさは分類だけでは決まりません。

// id="output"の要素があるページで、文字列として表示する例
const userInput = "<b>猫の名前</b>";
const output = document.getElementById("output");
if (output) {
  output.textContent = userInput; // タグとして解釈せず、そのまま表示
}
// innerHTMLはHTMLを解釈するため、未検証の値を渡さない

innerHTMLへscript要素を入れた場合、そのscriptがそのまま実行されるとは限りません。しかし、イベント属性など別の経路でスクリプトが動き得るため安全とはいえません。普通の文字表示にはtextContentを使い、HTMLを許可する必要がある場合は用途に合うサニタイザーを使い、許可しないタグや属性を取り除く処理(サニタイズ)を行います。

🛠️ XSS脆弱性を作り込まないためのポイント

対策は、値を入れる場所に合わせて選びます。記号を命令ではなく文字として扱わせる処理をエスケープと呼びますが、HTML本文向けの処理をURLやJavaScriptの中にもそのまま使えるとは限りません。

猫たちの席の境界を分けるように、プログラムでも「データ」と「命令」の境界を守りましょう。文字を表示するだけならHTMLに変換しない、という小さな選択が防御の基本になります。

参考資料