第 4 章 提案手法のツール化と実験
4.3 機能評価 (2) テストケースの生成とテストの実施
4.3.1 テストケースの生成による XSS の検証
RailsのXSSのエスケープ機能をバイパスしているアプリケーションを例に、そ
の検証をCucumberによるセキュリティテストで実施する。
コードからセキュリティ検証モデルを生成する際に、XSSのエスケープを明示 的にバイパスしている箇所がチェックされ、その警告を検証するためのテストケー ス(例Listing4.2)が振る舞いとデータフロー解析を元に生成される。
1 $ cucumber --tags @railroadmap_wip --format json --out cucumber.json 2 Using the default profile...
3 Rack::File headers parameter replaces cache_control after Rack 1.5.
4 @railroadmap_wip
5 Feature: XSS tests generated by RailroadMap 6
7 # Warning : RRMW0024
8 # XSS target : S_article#body 9 # trace tag : fRpzb4da16BAh 10 # Start state : V_article#new 11 # Input : S_article#body
12 # trans : T_V_article#new#0 render 13 # trans : T_V_article#_form#0 submit 14 # trans : T_C_article#create#0 redirect_to 15 # trans : T_C_article#show#0 render 16 # Output : V_article#show
17 # Order : 1st
18 Scenario: RRMW0024 - XTP_V_article#_form_to_V_article#show_0 # features/xss_test.
feature:15
19 Given I am logged in # features/
step_definitions/user_steps.rb:53
20 Given I am on the new_article page # features/
step_definitions/railroadmap_steps.rb:43
21 When I fill in xss_injection_msg with "fRpzb4da16BAh" for "Body" # features/
step_definitions/railroadmap_steps.rb:76
22 When I press "Create Article" # features/
step_definitions/railroadmap_steps.rb:54
23 Then I should see "fRpzb4da16BAh" in raw # features/
step_definitions/railroadmap_steps.rb:143
24 And I should see xss_escaped_msg in raw # features/
step_definitions/railroadmap_steps.rb:169
25 This XSS warning is True-Positive! (MiniTest::Assertion)
26 ./features/step_definitions/railroadmap_steps.rb:180:in ‘/^(?:|I )should see xss_escaped_msg in raw$/’
27 features/xss_test.feature:21:in ‘And I should see xss_escaped_msg in raw’
28
29 # Warning : RRMW0025 30 # XSS target : S_comment#body 31 # trace tag : WZT9mHALpFB2J
32 # Start state : V_comment#new => replaced
33 # replace : needs to add steps (create new article) before new comment 34 # Input : S_comment#body
35 # trans : T_V_comment#new#0 render 36 # trans : T_V_comment#_form#0 submit 37 # trans : T_C_comment#create#0 redirect_to 38 # trans : T_C_comment#show#0 render 39 # trans : T_V_comment#show#2 link_to Back2 40 # trans : T_C_article#index#0 render 41 # trans : T_V_article#index#0 link_to Show 42 # trans : T_C_article#show#0 render 43 # Output : V_article#show
44 # Order : 2nd
45 Scenario: RRMW0025 - XTP_V_comment#_form_to_V_article#show_0 # features/xss_test.
feature:39
46 Given I am logged in # features/
step_definitions/user_steps.rb:53
47 Given I am on the new_article page # features/
step_definitions/railroadmap_steps.rb:43
48 When I fill in "TEST1" for "Body" # features/
step_definitions/railroadmap_steps.rb:66
49 When I press "Create Article" # features/
step_definitions/railroadmap_steps.rb:54
50 When I follow "Add new comment" # features/
step_definitions/railroadmap_steps.rb:58
51 When I fill in xss_injection_msg with "WZT9mHALpFB2J" for "Body" # features/
step_definitions/railroadmap_steps.rb:76
52 When I press "Create Comment" # features/
step_definitions/railroadmap_steps.rb:54
53 When I follow "Back2" # features/
step_definitions/railroadmap_steps.rb:58
54 When I follow "Show" # features/
step_definitions/railroadmap_steps.rb:58
55 Then I should see "WZT9mHALpFB2J" in raw # features/
step_definitions/railroadmap_steps.rb:143
56 And I should see xss_escaped_msg in raw # features/
step_definitions/railroadmap_steps.rb:169
57 This XSS warning is True-Positive! (MiniTest::Assertion)
58 ./features/step_definitions/railroadmap_steps.rb:180:in ‘/^(?:|I )should see xss_escaped_msg in raw$/’
59 features/xss_test.feature:50:in ‘And I should see xss_escaped_msg in raw’
60
61 Failing Scenarios:
62 cucumber features/xss_test.feature:15 # Scenario: RRMW0024 - XTP_V_article#
_form_to_V_article#show_0
63 cucumber features/xss_test.feature:39 # Scenario: RRMW0025 - XTP_V_comment#
_form_to_V_article#show_0 64
65 2 scenarios (2 failed)
66 17 steps (2 failed, 15 passed) 67 0m1.161s
68 Created new window in existing browser session.
69 Coverage report generated for Cucumber Features to /home/sage/Dropbox/workspace/
securitytest4ror/rails3-bootstrap-devise-cancan-vul/coverage. 93 / 160 LOC (58.13%) covered.
Listing 4.2: Example cucumber test cases and execution log of XSS injection
このテスト結果を含めて、ダッシュボードには 図4.10のように警告として表示 される。
この作業を、4つのアプリケーションに対して適用した結果を表4.11 に示す。
最初のアプリケーションはツール評価のためのサンプルアプリケーションである。
残りの3つ(intranet10, redmine11, vellum12)はGithubで公開されている実際の アプリケーションを用いた。
確認方法であるが、C.1行に各アプリケーションからセキュリティ検証モデルを 抽出した際の状態遷移(State、Transition)とデータフロー数を示す。C.1-2行は
10https://github.com/fernandolopes/intranet
11https://github.com/redmine/redmine
12https://github.com/nbudin/vellum
図4.10: XSS警告のScreenshot (version 0.1)
Viewのコードでエスケープされた出力箇所の数を示す。C.1-2-1ではC.1-2で指 摘された箇所から一つをサンプルとして選択し、テストケースを生成する。その 結果、すべてのアプリケーションでエスケープ機能が実際に有効であることを確 認できた。このサンプリングテストの目的は、アプリケーションを実際に動作さ せることで、フレームワーク側のエスケープ処理が実際に有効であることを確認 する事である。
C.1-3行はViewのコードでRAWコマンドが用いられており、エスケープ機能 が無効化された箇所の数を示す。サンプルアプリケーションでは、2箇所XSS脆 弱性となるRAWFコマンドが仕組まれており、ツールはこの2箇所を検出しテス トコードを生成、テストの結果XSS脆弱性を持つことを確認した。
IntranetではRAWコマンドが用いられている箇所が16箇所あり、1箇所は、
Web上でのリッチなテキスト編集機能を提供するプラグイン、MCE13、 の利用 箇所であった。ただし、MCEを使ったコンテンツの編集機能は管理者権限でしか アクセスできないページであり、前提として受け入れ可能な範囲と思われる。残 りの15箇所については、実際には実装方法の問題で、Viewのコード修正を行う ことで解決する問題であった。
RedmineについてはRAWコマンドが用いられている箇所が9箇所あり、テス
ト可能な(JSONの処理でRAWコマンドを利用している)データパスが1箇所あ り、テストの結果、XSS攻撃が実際に可能であった。
VellumについてはRAWコマンドが用いられている箇所が2箇所あったが、こ
れらはMCEを使用した箇所であり、Intranetと同様に管理者権限でしかアクセス
13http://www.tinymce.com/
できないページであり、前提として受け入れ可能な範囲と思われる。
現在のRailsでは入力時のデータのサニタイズは行わず、出力時に一括してエ
スケープ処理を行っている。したがって、アプリケーション内部でHTMLを含む 出力メッセージを生成した場合は、RAWコマンドによりフレームワーク側のエス ケープ処理を無効化する。しかしながら、このアプリケーション内部処理に脆弱 性がある場合、アプリケーションのXSS脆弱性となる。この例では、本ツールで この問題の存在を証明することができた。
RAWコマンドを用いる場合は、XSSの脆弱性が含まれ無いことを保証すること はアプリケーション側の責任となる。開発者は、危険な箇所の把握と、その実装 に脆弱性がないことを、最終的にテストの形で確認することが重要である。
表4.11: Test result
Argument tree (process) Assessment results
App0 (sample app) App1 (intranet) App2 (redmine) App3 (vellum)
C.1: valid model (P.1: gen. model) # of state 72 256 875 179
# of transition 120 379 954 246
# of dataflow 100 371 1911 302
C.1-2: list all escaped outputs 68 285 1754 255
C.1-2-1: select the test path (P.5: gen. test-cases)
C.1-2-1-1: list test (P.7: run test) 1 1 1 1
C.1-2-1-1-1: test – pass 1 1 1 1
C.1-2-1-1-2: test – fail 0 0 0 0
C.1-3: list all “raw” outputs and data flows 2 16 9 2
C.1-3-1: appropriate “raw” usage (tool test) 15 NG (fixable) all ok all ok C.1-3-2: select the test path (P.5: gen. test-cases)
C.1-3-2-1: list un-testable output 0 – 8 0
C.1-3-2-2: list testable output (P.7: run test) 2 1 1 2
C.1-3-2-1-1: no dataflow path – 8 –
C.1-3-2-2-1: test – pass 0 0 0 0
C.1-3-2-2-2: test – fail 2(tool test) 1(MCE) 1 (fixable) 2(MCE)