Web Application Security Memo

ウェブセキュリティに関するメモ書き

OWASP ZAPのXSS(Cross-site scripting)診断は何をしているのか?

※当サイトにはプロモーションが含まれています。

公開日: 更新日:

OWASP ZAP

OWASP ZAPのActive Scanで行っている脆弱性診断にはいろいろな項目があります。ここでは、その中の1つである「XSS(Cross Site Scripting)」の診断が何をしているのか説明します。

OWASP ZAP 2.3.0 がリリースされたばかりですが、この記事の内容で調査したのは 2.2.2 です。

ZAP 2.2.2 が行うXSS診断の種類

ZAP 2.2.2のポリシーにはXSSに関する項目がデフォルトで1つだけ用意されていますが、「Active scanner rules (beta)」アドオンをインストールすることで、3つ追加されます。それらを以下に示します。それぞれに該当するソースファイル(クラス)へのリンクもつけておきます。

診断対象の脆弱性

上記4種の診断は、どれも以下の脆弱性を対象にしています。

CWE

WASC

ソースコード

今回はデフォルトで用意されている「Cross Site Scripting (Reflected)」について解説します。

上に書いたように TestCrossSiteScriptV2.javascan メソッドで診断が行われています。

処理概要

前提

  • scanメソッドが実行される時点で、診断対象となるURLが1つ決まっています。
  • Active Scanを実行する前に、このURLに対してスパイダリングもしくは手動でアクセスしているはずであり、その時に送信した各パラメータ(URLからのパラメータ, Formからのパラメータ等)毎にループ処理しています。
  • そのループの中で scanメソッドに、基のアクセスデータ・パラメータ名・パラメータ値とが渡されます。

処理概要

  1. 目印となる文字列(“0W45pz4p”)をパラメータにセットして診断対象URLにアクセスします。
  2. レスポンスヘッダもしくはレスポンスボディにこの文字列が出力されているか調べます。
  3. 出力されていなければ処理を終了します。
  4. 出力されている場合は、どのような位置に出力されているかによって攻撃に使用するJavaScript文字列(JavaScriptでない場合もあります)を決定します。
  5. 決定したJavaScript文字列をパラメータにセットして診断対象URLにアクセスします。
  6. 使用したJavaScript文字列がレスポンスヘッダもしくはレスポンスボディに出力されているか調べます。
  7. 出力されていれば脆弱性有りと判定します。

処理詳細

ソースコードで行っている処理を説明します。

  1. 目印となる文字列(“0W45pz4p”)をパラメータにセットして診断対象URLにアクセスします。(123行目)
    1. レスポンスヘッダもしくはレスポンスボディにこの文字列が見付からなければ、この文字列を小文字にした文字列が出力されていないかチェックします。(129行目)
    2. それでも見付からなければ、大文字にした文字列が出力されていないかチェックします。(133行目)
    3. それでも見付からなければ、基のパラメータ値に”0W45pz4p”をつなげた文字列でHTTP通信し、このつなげた文字列が出力されていないかチェックします。(137行目)
    4. それでも見付からなければ、パラメータに「’”」という文字列をセットしてHTTP通信し、レスポンスにこの文字列が含まれていれば脆弱性ありと判定して処理を終了します。(144行目あたり)
  2. ここまでの処理でレスポンス内に見つかった位置毎に以下の処理を行います。(複数見つかることもあるので)(154行目)
  3. HTMLタグの属性値の中に見つかった場合(159行目)
    1. その属性が、”onClick”のようなイベントだった場合(162行目)
      1. “;alert(1)” という文字列をパラメータにセットしてHTTP通信します。(165行目)
      2. レスポンス内の属性値にこの文字列が出力され、且つこの属性値が”onClick”のようなイベントであった場合、脆弱性有りと判定します。(168行目あたり)
    2. その属性が、action や src などURLを操作できる属性であった場合(181行目)
      1. “javascript:alert(1);” という文字列をパラメータにセットしてHTTP通信します。(183行目)
      2. レスポンスにこの文字列が出力されていれば脆弱性有りと判定します。(185行目)
    3. この時点で脆弱性有りの判定となっておらず、且つ frame, img, script 等、src属性を持つことのできるタグ内の属性であった場合(195行目)
      1. 「クォート文字」 + “src=http://badsite.com” という文字列をパラメータにセットしてHTTP通信します。(197行目)
        • このクォート文字は”0W45pz4p”が見つかった部分で使用されていたクォート文字が使われます。
      2. レスポンスにこの文字列が出力されていれば脆弱性有りと判定します。(200行目)
    4. まだ脆弱性有り判定になっていない場合(210行目)
      1. 「クォート文字」+ “>” という文字列をパラメータにセットしてHTTP通信します。(212行目)
        • このクォート文字は”0W45pz4p”が見つかった部分で使用されていたクォート文字が使われます。
      2. レスポンスにこの文字列が出力されていれば脆弱性有りと判定します。(214行目あたり)
    5. まだ脆弱性有り判定になっていない場合(224行目)
      1. 「クォート文字」+ 「半角スペース」+ “onMouseOver=” + 「クォート文字」+ “alert(1);” という文字列をパラメータにセットしてHTTP通信します。(226行目)
        • このクォート文字は”0W45pz4p”が見つかった部分で使用されていたクォート文字が使われます。
      2. レスポンスにこの文字列が出力されていれば脆弱性有りと判定します。(229行目)
  4. HTMLコメントの中に見つかった場合(239行目)
    1. ”–><!–” という文字列をパラメータにセットしてHTTP通信します。(241行目あたり)
    2. レスポンスにこの文字列が出力されていれば脆弱性有りと判定します。(243行目)
    3. 見つからない場合(248行目)
      1. ”–>test<!–” という文字列をパラメータにセットしてHTTP通信します。(250行目)
        • scriptタグがブロックされている場合を想定しています。
      2. レスポンスにこの文字列が出力されていれば脆弱性有りと判定します。(252行目)
  5. それ以外の場合
    1. bodyタグ直下に見つかった場合(261行目)
      1. ” という文字列をパラメータにセットしてHTTP通信します。(264行目)
      2. レスポンスにこの文字列が出力されていれば脆弱性有りと判定します。(266行目)
      3. 見付からなかった場合(271行目)
        1. test” という文字列をパラメータにセットしてHTTP通信します。(273行目)
        2. レスポンスにこの文字列が出力されていて、且つそれがbodyタグ直下 もしくは scriptタグ内であった場合は、脆弱性有りと判定します。(276行目)
    2. タグで囲まれていた場合(286行目)
      1. ”</” + そのタグ名 + “><” + そのタグ名 + “>” という文字列をパラメータにセットしてHTTP通信します。(288行目)
      2. レスポンスにこの文字列が出力されていれば脆弱性有りと判定します。(291行目)
      3. 見付からなかった 且つ scriptタグで囲まれていた場合(296行目)
        1. 「クォート文字」+ “;alert(1);” + 「クォート文字」という文字列をパラメータにセットしてHTTP通信します。(298行目)
          • このクォート文字は”0W45pz4p”が見つかった部分で使用されていたクォート文字が使われます。
          • scriptタグ内のクォート文字で囲まれた部分に出力された場合は、クォート文字でクォートを閉じます。
        2. レスポンスにこの文字列が出力されていれば脆弱性有りと判定します。(300行目)

メモ

  • 当たり前ですが、パラメータがないノード(URL)に対しては何もしません。

[最終更新日: 2014年4月11日]