-
Notifications
You must be signed in to change notification settings - Fork 2
/
test_case.rb
159 lines (136 loc) · 13.2 KB
/
test_case.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
class TestCase
attr_accessor :id, :expect, :title, :header, :template, :options, :version, :load_uri
@@testcases = {}
@@testcase_id = 0
def initialize(id, expect, title, header, template, options, version = 1.0)
@id = id
@expect = expect
@title = title
@header = header
@template = template
@options = options
@version = version
@load_uri = "/test/" + (options[:load_part] || "load") + "/" + id.to_s + "?" + (options[:query] || "")
end
def uri (request)
host = ""
if (options[:include_host])
host = (options[:protocol] || "http") + "://" + request.host + port(request)
elsif (options[:include_other_host])
host = (options[:protocol] || "http") + "://" + (request.host == APP_CONFIG["origin1"] ? APP_CONFIG["origin2"] : APP_CONFIG["origin1"]) + port(request)
elsif (options[:redirect])
host = "http://" + (request.host == APP_CONFIG["origin1"] ? APP_CONFIG["origin2"] : APP_CONFIG["origin1"]) + port(request)
end
host + (options[:redirect] ? "/redirect" : "/test") + (expect ? "/pass" : "/fail") + "/" + id.to_s + "?_=" + Time.new().to_f().to_s
end
def port(request)
(request.port == 80 ? "" : (":" + request.port.to_s))
end
def self.version(version)
self.all.find_all{ |t| t.version <= version }
end
def self.all
self.checkload()
@@testcases.values
end
def self.get_testcase(id)
self.checkload()
@@testcases[id.to_s]
end
def self.testcase(expect, title, header, template, options = {}, version = 1.0)
@id = @@testcase_id
@@testcase_id = @@testcase_id + 1
@@testcases[@id.to_s] = TestCase.new(@id, expect, title, header, template, options, version)
end
def self.checkload()
@@testcases = @@testcases || {}
if (@@testcases.length == 0)
self.load()
end
end
def self.load()
self.load_1_0()
self.load_1_1_draft()
end
def self.load_1_0()
self.create_testcases("stylesheet", "style-src", "linked_style.erb", "")
self.testcase(true, "Style in data-uri allowed", "default-src 'self'; style-src data: ", "linked_style_data.erb", { :include_host => true })
self.testcase(false, "Style in data-uri disallowed", "default-src 'self'; style-src 'self'", "linked_style_data.erb", { :include_host => true })
self.testcase(true, "Use inline styles", "default-src 'self'; style-src 'self' 'unsafe-inline'", "inline_style.erb")
self.testcase(false, "Use inline styles violation", "style-src 'self'", "inline_style.erb")
self.testcase(true, "Use inline style attributes", "style-src 'self' 'unsafe-inline'", "inline_style_attr.erb")
self.testcase(false, "Use inline style attributes violation", "style-src 'self'", "inline_style_attr.erb")
self.create_testcases("script", "script-src", "linked_script.erb","")
self.testcase(true, "Script in data-uri allowed", "default-src 'self'; script-src data: ", "linked_script_data.erb", { :include_host => true })
self.testcase(false, "Script in data-uri disallowed", "default-src 'self'; script-src 'self'", "linked_script_data.erb", { :include_host => true })
self.testcase(true, "Use inline script", "script-src 'unsafe-inline'", "inline_script_tag.erb")
self.testcase(false, "Use inline script violation", "script-src 'self'", "inline_script_tag.erb")
self.testcase(true, "Use inline script in event handler", "script-src 'unsafe-inline'", "inline_script_eventhandler.erb")
self.testcase(false, "Use inline script in event handler violation", "script-src 'self'", "inline_script_eventhandler.erb")
self.testcase(true, "Use eval in script", "script-src 'unsafe-eval' 'unsafe-inline'", "eval_script.erb")
self.testcase(false, "Use eval in script violation", "script-src 'unsafe-inline'", "eval_script.erb")
self.testcase(true, "Use eval in script Function", "script-src 'unsafe-eval' 'unsafe-inline'", "eval_script_function.erb")
self.testcase(false, "Use eval in script Function violation", "script-src 'unsafe-inline'", "eval_script_function.erb")
self.testcase(true, "Use eval in script setTimeout", "script-src 'unsafe-eval' 'unsafe-inline'", "eval_script_settimeout.erb")
self.testcase(false, "Use eval in script setTimeout violation", "script-src 'unsafe-inline'", "eval_script_settimeout.erb")
self.testcase(true, "Use script setTimeout function", "script-src 'unsafe-inline'", "script_settimeout_function.erb")
self.testcase(true, "Use eval in script setInterval", "script-src 'unsafe-eval' 'unsafe-inline'", "eval_script_setinterval.erb")
self.testcase(false, "Use eval in script setInterval violation", "script-src 'unsafe-inline'", "eval_script_setinterval.erb")
self.testcase(true, "Use script setInterval function", "script-src 'unsafe-inline'", "script_setinterval_function.erb")
self.create_testcases("image", "img-src", "img.erb", "")
self.testcase(true, "Style wants image, and allowed by img-src", "default-src 'self'; img-src 'self'; style-src 'unsafe-inline'", "inline_style.erb")
self.testcase(false, "Style wants image, but disallowed by img-src", "default-src 'self'; img-src 'none'; style-src 'unsafe-inline'", "inline_style.erb")
self.create_testcases("object", "object-src", "object.erb", "", {:tag => "object", :attr => "data", :extra => " type=\"application/x-shockwave-flash\""})
self.create_testcases("embed", "object-src", "object.erb", "", {:tag => "embed", :attr => "src", :extra => " type=\"application/x-shockwave-flash\""})
# not reliable self.create_testcases("applet", "object-src", "object.erb", "", {:tag => "applet", :attr => "codebase", :extra => " code=\"HelloWorld.class\""})
self.create_testcases("frame", "frame-src", "iframe.erb", "")
self.create_testcases("font", "font-src", "font.erb", ";style-src 'unsafe-inline")
self.create_testcases("audio", "media-src", "media.erb", "", {:tag => "audio"})
self.create_testcases("video", "media-src", "media.erb", "", {:tag => "video"})
self.create_testcases("xhr", "connect-src", "connect_xhr.erb", ";script-src 'self' 'unsafe-inline'")
self.create_testcase_list_standard("EventSource", "connect-src", "'self'", "connect_eventsource.erb", ";script-src 'self' 'unsafe-inline'")
self.create_testcase_list_standard("EventSource", "connect-src", "{host}", "connect_eventsource.erb", ";script-src 'self' 'unsafe-inline'")
self.create_testcase_list_standard("WebSockets", "connect-src", "ws://{host}" , "connect_websockets.erb", ";script-src 'self' 'unsafe-inline'", {:protocol => "ws", :include_host => true})
end
def self.load_1_1_draft()
self.testcase(true, "Form-action 'self'", "form-action 'self'; script-src 'unsafe-inline'", "form_action.erb", {}, 1.1)
self.testcase(true, "Form-action {host}", "form-action {host}; script-src 'unsafe-inline'", "form_action.erb", {}, 1.1)
self.testcase(false, "Form-action 'none'", "form-action 'none'; script-src 'unsafe-inline'", "form_action.erb", {}, 1.1)
self.testcase(true, "Form-action {other_host}", "form-action {other_host}; script-src 'unsafe-inline'", "form_action.erb", { :include_other_host => true }, 1.1)
self.testcase(false, "Form-action {other_host} but post to self", "form-action {other_host}; script-src 'unsafe-inline'", "form_action.erb", {}, 1.1)
self.testcase(false, "Form-action with redirect from allowed to disallowed", "form-action {other_host}; script-src 'unsafe-inline'", "form_action.erb", {:redirect => true}, 1.1)
self.testcase(true, "Form-action with redirect from allowed to allowed", "form-action {origin1} {origin2}; script-src 'unsafe-inline'", "form_action.erb", {:redirect => true}, 1.1)
self.testcase(true, "Script-nonce correct", "script-nonce correctnonce; script-src 'unsafe-inline' ", "script_nonce.erb", {:nonce_attribute => "nonce=\"correctnonce\""}, 1.1)
self.testcase(false, "Script-nonce wrong", "script-nonce somenonce; script-src 'unsafe-inline' ", "script_nonce.erb", {:nonce_attribute => "nonce=\"wrongnonce\""}, 1.1)
self.testcase(false, "Script-nonce missing", "script-nonce somenonce; script-src 'unsafe-inline' ", "script_nonce.erb", {:nonce_attribute => ""}, 1.1)
self.testcase(false, "Script-nonce set and javascript in event handler", "script-nonce somenonce; script-src 'unsafe-inline' ", "script_nonce_eventhandler.erb", {}, 1.1)
self.testcase(false, "Script-nonce empty in header", "script-nonce ; script-src 'unsafe-inline' ", "script_nonce.erb", {:nonce_attribute => ""}, 1.1)
self.testcase(false, "Script-nonce empty in header but not on tag", "script-nonce ; script-src 'unsafe-inline' ", "script_nonce.erb", {:nonce_attribute => "nonce=\"somenonce\""}, 1.1)
self.testcase(false, "Script-nonce set and javascript in event handler", "script-nonce ; script-src 'unsafe-inline' ", "script_nonce_eventhandler.erb", {}, 1.1)
self.testcase(false, "Script-nonce invalid", "script-nonce nonce nonce; script-src 'unsafe-inline' ", "script_nonce.erb", {:nonce_attribute => "nonce=\"nonce nonce\""}, 1.1)
self.testcase(false, "Script-nonce invalid in header and missing on tag", "script-nonce nonce nonce; script-src 'unsafe-inline' ", "script_nonce.erb", {:nonce_attribute => ""}, 1.1)
self.testcase(false, "Script-nonce invalid and javascript in event handler", "script-nonce nonce nonce; script-src 'unsafe-inline' ", "script_nonce_eventhandler.erb", {}, 1.1)
self.testcase(true, "Plugin-types embed allowed", "default-src 'self'; plugin-types application/x-shockwave-flash", "object.erb", {:tag => "embed", :attr => "src", :extra => " type=\"application/x-shockwave-flash\""}, 1.1)
self.testcase(false, "Plugin-types embed disallowed", "default-src 'self'; plugin-types application/x-shockwave-flash", "object.erb", {:tag => "embed", :attr => "src", :extra => " type=\"application/pdf\""}, 1.1)
self.testcase(true, "Plugin-types object allowed", "default-src 'self'; plugin-types application/x-shockwave-flash", "object.erb", {:tag => "object", :attr => "data", :extra => " type=\"application/x-shockwave-flash\""}, 1.1)
self.testcase(false, "Plugin-types object disallowed", "default-src 'self'; plugin-types application/x-shockwave-flash", "object.erb", {:tag => "object", :attr => "data", :extra => " type=\"application/pdf\""}, 1.1)
self.testcase(true, "Plugin-types bare - not set", "default-src 'self'", "", {:load_part => "flash", :query => "pass=true"}, 1.1)
self.testcase(true, "Plugin-types bare - allowed", "default-src 'self'; plugin-types application/x-shockwave-flash", "", {:load_part => "flash", :query => "pass=true"}, 1.1)
self.testcase(false, "Plugin-types bare - disallowed", "default-src 'self'; plugin-types application/x-shockwave-flash", "", {:load_part => "flash", :query => "pass=false"}, 1.1)
end
def self.create_testcases(type, directive, template, additional, options = {}, version = 1.0)
self.create_testcase_list(type, directive, "'self'", template, additional, options, version)
self.create_testcase_list(type, directive, "{host}", template, additional, options, version)
end
def self.create_testcase_list(type, directive, value, template, additional, options = {}, version = 1.0)
self.create_testcase_list_standard(type, directive, value, template, additional, options, version)
self.testcase(false, "Load " + type + " from " + directive + " with redirect from allowed to disallowed", directive + " {other_host}" + additional, template, {:redirect => true}.merge(options), version)
self.testcase(true, "Load " + type + " from " + directive + " with redirect from allowed to allowed", directive + " {origin1} {origin2}" + additional, template, {:redirect => true}.merge(options), version)
end
def self.create_testcase_list_standard(type, directive, value, template, additional, options = {}, version = 1.0)
self.testcase(true, "Load " + type + " from default-src " + value, "default-src " + value + additional, template, options, version)
self.testcase(false, "Load " + type + " from default-src 'none'", "default-src 'none'" + additional, template, options, version)
self.testcase(true, "Load " + type + " from " + directive + " " + value, "default-src 'none'; " + directive + " " + value + additional, template, options, version)
self.testcase(false, "Load " + type + " from " + directive + " 'none'", "default-src " + value + "; " + directive + " 'none'" + additional, template, options, version)
end
end