Skip to content

Commit 07367a2

Browse files
committed
bug fixes and tests for filtered directives
1 parent a5f7d76 commit 07367a2

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

lib/secure_headers/headers/content_security_policy.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ module Constants
6767
DIRECTIVES_2_0 + DIRECTIVES_DRAFT
6868
).freeze
6969

70-
ALL_DIRECTIVES = [DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0 + DIRECTIVES_DRAFT].flatten.uniq
70+
ALL_DIRECTIVES = [DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0 + DIRECTIVES_DRAFT].flatten.sort.uniq
7171
CONFIG_KEY = :csp
7272
end
7373

@@ -274,21 +274,24 @@ def translate_dir_value val
274274
end
275275
end
276276

277+
# ensures defualt_src is first and report_uri is last
277278
def generic_directives
278-
header_value = ''
279+
header_value = build_directive(:default_src)
279280
data_uri = @disable_img_src_data_uri ? [] : ["data:"]
280281
if @config[:img_src]
281282
@config[:img_src] = @config[:img_src] + data_uri unless @config[:img_src].include?('data:')
282283
else
283284
@config[:img_src] = @config[:default_src] + data_uri
284285
end
285286

286-
ALL_DIRECTIVES.each do |directive_name|
287+
(ALL_DIRECTIVES - [:default_src, :report_uri]).each do |directive_name|
287288
if @config[directive_name]
288289
header_value += build_directive(directive_name)
289290
end
290291
end
291292

293+
header_value += build_directive(:report_uri) if @config[:report_uri]
294+
292295
header_value.strip
293296
end
294297

spec/lib/secure_headers/headers/content_security_policy_spec.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,27 @@ def request_for user_agent, request_uri=nil, options={:ssl => false}
143143
end
144144

145145
describe "#value" do
146+
context "browser sniffing" do
147+
let(:complex_opts) do
148+
ALL_DIRECTIVES.inject({}) { |memo, directive| memo[directive] = "'self'"; memo }.merge(:block_all_mixed_content => '')
149+
end
150+
151+
it "does not filter any directives for Chrome" do
152+
policy = ContentSecurityPolicy.new(complex_opts, :request => request_for(CHROME))
153+
expect(policy.value).to eq("default-src 'self'; base-url 'self'; block-all-mixed-content ; child-src 'self'; connect-src 'self'; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src 'self' data:; media-src 'self'; object-src 'self'; plugin-types 'self'; sandbox 'self'; script-src 'self'; style-src 'self'; report-uri 'self';")
154+
end
155+
156+
it "filters blocked-all-mixed-content, child-src, and plugin-types for firefox" do
157+
policy = ContentSecurityPolicy.new(complex_opts, :request => request_for(FIREFOX))
158+
expect(policy.value).to eq("default-src 'self'; base-url 'self'; connect-src 'self'; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src 'self' data:; media-src 'self'; object-src 'self'; sandbox 'self'; script-src 'self'; style-src 'self'; report-uri 'self';")
159+
end
160+
161+
it "filters base-url, blocked-all-mixed-content, child-src, form-action, frame-ancestors, and plugin-types for safari" do
162+
policy = ContentSecurityPolicy.new(complex_opts, :request => request_for(SAFARI))
163+
expect(policy.value).to eq("default-src 'self'; connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self' data:; media-src 'self'; object-src 'self'; sandbox 'self'; script-src 'self'; style-src 'self'; report-uri 'self';")
164+
end
165+
end
166+
146167
it "raises an exception when default-src is missing" do
147168
csp = ContentSecurityPolicy.new({:script_src => 'anything'}, :request => request_for(CHROME))
148169
expect {

0 commit comments

Comments
 (0)