Skip to content

Commit

Permalink
raise errors when child/frame-src values don't match
Browse files Browse the repository at this point in the history
  • Loading branch information
oreoshake committed Jul 18, 2017
1 parent 4815c26 commit a998572
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 39 deletions.
10 changes: 2 additions & 8 deletions lib/secure_headers/headers/content_security_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,12 @@ def value

private

# frame-src is deprecated, child-src is being implemented. They are
# very similar and in most cases, the same value can be used for both.
def normalize_child_frame_src
if @config.frame_src && @config.child_src && @config.frame_src != @config.child_src
Kernel.warn("#{Kernel.caller.first}: [DEPRECATION] both :child_src and :frame_src supplied and do not match. This can lead to inconsistent behavior across browsers.")
raise ArgumentError, "#{Kernel.caller.first}: both :child_src and :frame_src supplied and do not match. This can lead to inconsistent behavior across browsers."
end

if supported_directives.include?(:child_src)
@config.child_src || @config.frame_src
else
@config.frame_src || @config.child_src
end
@config.frame_src || @config.child_src
end

# Private: converts the config object into a string representing a policy.
Expand Down
18 changes: 4 additions & 14 deletions spec/lib/secure_headers/headers/content_security_policy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,10 @@ module SecureHeaders
ContentSecurityPolicy.new(default_src: %w('self'), frame_src: %w('self')).value
end

it "emits a warning when child-src and frame-src are supplied but are not equal" do
expect(Kernel).to receive(:warn).with(/both :child_src and :frame_src supplied and do not match./)
ContentSecurityPolicy.new(default_src: %w('self'), child_src: %w(child-src.com), frame_src: %w(frame-src,com)).value
end

it "will still set inconsistent child/frame-src values to be less surprising" do
expect(Kernel).to receive(:warn).at_least(:once)
firefox = ContentSecurityPolicy.new({default_src: %w('self'), child_src: %w(child-src.com), frame_src: %w(frame-src,com)}, USER_AGENTS[:firefox]).value
firefox_transitional = ContentSecurityPolicy.new({default_src: %w('self'), child_src: %w(child-src.com), frame_src: %w(frame-src,com)}, USER_AGENTS[:firefox46]).value
expect(firefox).not_to eq(firefox_transitional)
expect(firefox).to match(/frame-src/)
expect(firefox).not_to match(/child-src/)
expect(firefox_transitional).to match(/child-src/)
expect(firefox_transitional).not_to match(/frame-src/)
it "raises an error when child-src and frame-src are supplied but are not equal" do
expect {
ContentSecurityPolicy.new(default_src: %w('self'), child_src: %w(child-src.com), frame_src: %w(frame-src,com)).value
}.to raise_error(ArgumentError)
end

it "supports strict-dynamic" do
Expand Down
21 changes: 4 additions & 17 deletions spec/lib/secure_headers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ module SecureHeaders
expect(hash[ContentSecurityPolicyConfig::HEADER_NAME]).to eq("default-src 'self'; script-src mycdn.com 'unsafe-inline' anothercdn.com")
end

it "appends child-src to frame-src" do
it "child-src and frame-src must match" do
Configuration.default do |config|
config.csp = {
default_src: %w('self'),
Expand All @@ -185,23 +185,10 @@ module SecureHeaders
end

SecureHeaders.append_content_security_policy_directives(chrome_request, child_src: %w(child_src.com))
hash = SecureHeaders.header_hash_for(chrome_request)
expect(hash[ContentSecurityPolicyConfig::HEADER_NAME]).to eq("default-src 'self'; child-src frame_src.com child_src.com; script-src 'self'")
end

it "appends frame-src to child-src" do
Configuration.default do |config|
config.csp = {
default_src: %w('self'),
child_src: %w(child_src.com),
script_src: %w('self')
}
end

safari_request = Rack::Request.new(request.env.merge("HTTP_USER_AGENT" => USER_AGENTS[:safari6]))
SecureHeaders.append_content_security_policy_directives(safari_request, frame_src: %w(frame_src.com))
hash = SecureHeaders.header_hash_for(safari_request)
expect(hash[ContentSecurityPolicyConfig::HEADER_NAME]).to eq("default-src 'self'; frame-src child_src.com frame_src.com; script-src 'self'")
expect {
SecureHeaders.header_hash_for(chrome_request)
}.to raise_error(ArgumentError)
end

it "supports named appends" do
Expand Down
1 change: 1 addition & 0 deletions upgrading-to-4-0.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The new default policy is:
## CSP configuration

* Setting `report_only: true` in a CSP config will raise an error. Instead, set `csp_report_only`.
* Setting `frame_src` and `child_src` when values don't match will raise an error. Just use `frame_src`.


## All cookies default to secure/httponly
Expand Down

0 comments on commit a998572

Please sign in to comment.