XSSとは

XSSクロスサイトスクリプティング(Cross Site Scripting)の略称で、そのまま略すとCSSとなり、Cascading Style Sheetsと誤解を生むため、XSSと呼ばれている。

XSSはWebアプリケーションの脆弱性もしくはそれを利用した攻撃のことをいい、ウェブサイト自体に対してではなく、そのウェブサイトのページを閲覧している利用者に影響する。

image.png 安全なウェブサイトの作り方 - 1.5 クロスサイト・スクリプティング

発生しうる脅威

クロスサイト・スクリプティング攻撃により、発生しうる脅威は次のもの。

  • 本物サイト上に偽のページが表示される

  • ブラウザが保存しているCookieを取得される

    • セッションIDがCookieに格納されていると、更に利用者へのなりすましにつながる
    • Cookie に個人情報等が格納されている場合、その情報が漏えいする
  • 任意のCookieをブラウザに保存させられる

XSSの種類

XSSは主に三つの種類に分類される。

  • 反射型クロスサイトスクリプティング (非持続的)

    サーバは、HTTPリクエストからデータを直接読み込み、読み込んだデータをHTTPレスポンスで返す。反射型XSS攻撃では、脆弱なWebアプリケーションに対して、攻撃者が被害者に危険なコンテンツを送信させる際に発生する。この危険なコンテンツは、被害者に返され Web ブラウザ上で実行される。

    一般的な手段として、次のような手順で実行される。

    1. 悪意あるコンテンツを URL のパラメータに含めて公の場に掲示
    2. 攻撃者は被害者を信じ込ませて悪意あるURLにアクセスさせる
    3. 悪意あるサイトが攻撃者のコンテンツを被害者に返す
    4. 被害者のブラウザ上で攻撃者のコンテンツが実行される
    
  • 格納型クロスサイトスクリプティング (持続的)

    アプリケーションは、危険なデータを何かしらの方法で記憶する(データベース、メッセージフォーラム、訪問者のログ、または他の信頼できるデータストア)。このデータは、その後、このアプリケーションに読み戻され、動的コンテンツの中に含まれる。

    例えば、管理者によるログ参照の際に適切に扱われないログメッセージにXSSを挿入することで、特別な権限を有するユーザになりすまし、権限が必要な操作を実施するなどの悪用方法がある。

  • DOMベースのクロスサイトスクリプティング

    他2つのXSSでは、サーバがWebページに対してXSSを挿入するが、DOMベースのXSSでは、クライアントがXSSをWebページに挿入する。例えば、ユーザが投稿する前にフォーム上で内容確認をするような状況が当てはまる。

    つまり、サーバの提供するスクリプトが、ユーザの提供するデータを処理した後に、そのスクリプトを (動的HTML等の手段により) Web ページに埋め込んで返すと、DOMベースのXSSとなる。

注意すべきページの特徴

次のようなサイトは特に注意が必要。

  • Cookieを利用してログインのセッション管理を行っているサイト
  • ログイン画面、個人情報の入力画面等のフィッシング詐欺ターゲットになりやすいページを持つサイト

より具体的には次のような機能を持つページはXSS脆弱性が生じやすい。

  • 入力内容を確認させる表示画面(会員登録、アンケート等)
  • 誤入力時の再入力を要求する画面で、前の入力内容を表示するとき
  • 検索結果の表示
  • エラー表示
  • コメントの反映(ブログ、掲示板等) 等

対策の種類

クロスサイト・スクリプティング脆弱性への対策は、ウェブアプリケーションの性質に合わせ、次の3つに分類される

  • HTMLテキストの入力を許可しない場合の対策

    検索機能や個人情報の登録等、HTMLタグ等を用いた入力を許可する必要がないもの。多くのアプリケーションはここに該当する。

  • HTMLテキストの入力を許可する場合の対策

    自由度の高い掲示板やブログ等。例えば、利用者が入力文字の色やサイズを指定できる機能等を実装するために、HTMLテキストの入力を許可する掲示板など。

  • 全てのウェブアプリケーションに共通の対策

    上の2つの両者に共通して必要な対策。

HTMLテキストの入力を許可しない場合の対策

根本的解決は次のもの。

  • ウェブページに出力する全ての要素に対して、エスケープ処理を施す

    • ウェブページの表示に影響する特別 な記号文字(<>&等)を、HTML エンティティ(&lt;&gt;&amp;等)に置換する
    • HTML タグを出力する場合は、その属性値を必ずダブルクオート(")で括り、ダブルクオートで括られた属性値に含まれる"を、HTMLエンティティ(&quot;)に置換する
  • URLを出力するときは、http://https://で始まるURLのみを許可する
  • <script>...</script> 要素の内容を動的に生成しない。
  • スタイルシートを任意のサイトから取り込めるようにしない

上記に加えて、保険的に次のような対策もある。(保険的対策は根本を解決できるものではないため、名前の通り保険的な対策として導入する)

  • 入力値の内容チェックを行う

HTMLテキストの入力を許可する場合の対策

根本的解決は次のもの。

  • 入力されたHTMLテキストから構文解析木を作成し、スクリプトを含まない必要な要素のみを抽出する

    構文解析を行い、「ホワイトリスト方式」で許可する要素のみを抽出する。この方法は、複雑なコーディングが要求され、処理に負荷がかかる影響もあるため、十分な検討が必要。

上記に加えて、保険的に次のような対策もある。

  • 入力されたHTMLテキストから、スクリプトに該当する文字列を排除する

全てのウェブアプリケーションに共通の対策

根本的解決は次のもの。

  • HTTPレスポンスヘッダのContent-Typeフィールドに文字コード(charset)を指定する

上記に加えて、保険的に次のような対策もある。

  • Cookie情報の漏えい対策として、発行するCookieにHttpOnly属性を加え、 TRACE メソッドを無効化する
  • クロスサイト・スクリプティング潜在的脆弱性対策として有効なブラウザの機能を 有効にするレスポンスヘッダを返す

参考サイト