XSS (クロスサイト・スクリプティング)⚓︎
XSS とは⚓︎
安全なウェブサイトの作り方 - 1.5 クロスサイト・スクリプティング | 情報セキュリティ | IPA 独立行政法人 情報処理推進機構 より XSS の定義を以下に引用します。
ウェブアプリケーションの中には、検索のキーワードの表示画面や個人情報登録時の確認画面、掲示板、ウェブのログ統計画面等、利用者からの入力内容やHTTPヘッダの情報を処理し、ウェブページとして出力するものがあります。ここで、ウェブページへの出力処理に問題がある場合、そのウェブページにスクリプト等を埋め込まれてしまいます。この問題を「クロスサイト・スクリプティングの脆弱性」と呼び、この問題を悪用した攻撃手法を、「クロスサイト・スクリプティング攻撃」と呼びます。
AlesInfiny Maia OSS Edition での XSS 対策⚓︎
原則として以下の方針をとります。
- アプリケーション外から取得した値(クライアントからの入力値、データベースから取得した値など)を画面に出力する際は文字列をプレーンテキスト化することで HTML や JavaScript として解釈させない
CSR アプリケーション⚓︎
フロントエンドを Vue.js で構築する場合、 XSS 対策として以下の方針をとります。
-
アプリケーション外から取得した値を画面に文字列として出力するときは、常に
{{ }}で囲む(マスタッシュ構文)Vue.js では、
{{ }}で囲んだ文字列内の特殊文字は HTML エンコードされて出力されるため、アプリケーション外から取得した値を画面に出力する箇所では必ず{{ }}で囲むようにします。 -
アプリケーション外から取得した値を
<a>タグのhref属性に設定する場合は値を無害化するVue.js では動的な属性のバインディング時にも自動でエスケープ処理されるため、アプリケーション外から取得した値を HTML の属性に設定することを禁止しません。ただし、以下のようなコードの場合、
javascript:の使用による JavaScript の実行を防ぐことができません。1 2 3
<a v-bind:href="アプリケーション外から取得した値"> リンクをクリック </a>そのため、アプリケーション外から取得した値を
<a>タグのhref属性に設定する場合は以下のように対策します。- URL を解析し、アプリケーションで使用を許可する URL スキームを許可リストで検証する(
javascript:、data:、vbscript:などのスキームは受け付けない) - sanitize-url 等のライブラリを使用して値を無害化する
入力値の形式が正しい URL であっても、リンク先のコンテンツが安全とは限らないことに注意してください。
- URL を解析し、アプリケーションで使用を許可する URL スキームを許可リストで検証する(
-
アプリケーション外から取得した値をテンプレートとして出力することを禁止する
v-htmlや描画関数を使用してアプリケーション外から取得した値をそのまま出力してはなりません。XSS に対して脆弱なコード例① 1 2 3 4
new Vue({ el: '#app', template: `<div>` + アプリケーション外から取得した値 + `</div>` })XSS に対して脆弱なコード例② 1<div v-html="アプリケーション外から取得した値"></div>
アプリケーションを設計する上での注意事項
CMS ライクな機能を提供する場合など、エンドユーザーに HTML を直接入力させたい場面があるかもしれません。その場合も、たとえば画面上には HTML のタグや属性を選択肢として表示し、選択された値に応じて画面を構成するなどして、入力値を直接画面に出力することは極力避けてください。
SSR アプリケーション⚓︎
Thymeleaf と Spring MVC でアプリケーションを構築する場合、 XSS 対策として以下の方針をとります。
-
アプリケーション外から取得した値を画面に文字列として出力するときは、常に
th:textを使用するThymeleaf では
th:text属性に設定した値は HTML エンコードされて出力されるため、アプリケーション外から取得した値を画面に出力する箇所では必ずth:textを使用します。 -
インライン記法を使用する場合は、
[[${user.name}]]のように、[を 2 つ使用するHTML のテキストコンテキストでは
[[~]]で囲まれた値がth:textと同様に HTML エンコードされて出力されます。 JavaScript や CSS に埋め込む場合は、th:inline="javascript"やth:inline="css"を指定してコンテキストに応じてエスケープします。 -
アプリケーション外から取得した値を
<a>タグのth:href属性に設定する場合は値を無害化する具体的には、以下のように対策します。
Modelをバインドする場合は、 Hibernate Validator の@URLアノテーションを使用する- URL を解析し、アプリケーションで使用を許可する URL スキームを許可リストで検証する(
javascript:、data:、vbscript:などのスキームは受け付けない) - 必要に応じて許可するホストを限定する
入力値の形式が正しい URL であっても、リンク先のコンテンツが安全とは限らないことに注意してください。