diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header-crlf.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header-crlf.html new file mode 100644 index 000000000000..87bda1bf502d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header-crlf.html @@ -0,0 +1,144 @@ + + + +Embedded Enforcement: Sec-Required-CSP header. + + + + + + + + diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/support/echo-required-csp.py b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/support/echo-required-csp.py index 930a1f608538..6063cc046ba7 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/support/echo-required-csp.py +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/support/echo-required-csp.py @@ -1,8 +1,13 @@ import json def main(request, response): - header = request.headers.get("Sec-Required-CSP"); message = {} + + header = request.headers.get("Test-Header-Injection"); + message['test_header_injection'] = header if header else None + + header = request.headers.get("Sec-Required-CSP"); message['required_csp'] = header if header else None + second_level_iframe_code = "" if "include_second_level_iframe" in request.GET: if "second_level_iframe_csp" in request.GET and request.GET["second_level_iframe_csp"] <> "": diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/support/testharness-helper.sub.js b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/support/testharness-helper.sub.js index 127a94ba359f..6d2e64f8f7e9 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/support/testharness-helper.sub.js +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/support/testharness-helper.sub.js @@ -91,6 +91,10 @@ function assert_required_csp(t, url, csp, expected) { assert_unreached('Child iframes have unexpected csp:"' + e.data['required_csp'] + '"'); expected.splice(expected.indexOf(e.data['required_csp']), 1); + + if (e.data['test_header_injection'] != null) + assert_unreached('HTTP header injection was successful'); + if (expected.length == 0) t.done(); })); diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc index 51399e7d6e08..8f9382c7f67d 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc @@ -1843,6 +1843,10 @@ bool ContentSecurityPolicy::ShouldBypassContentSecurityPolicy( // static bool ContentSecurityPolicy::IsValidCSPAttr(const String& attr, const String& context_required_csp) { + // we don't allow any newline characters in the CSP attributes + if (attr.Contains('\n') || attr.Contains('\r')) + return false; + ContentSecurityPolicy* attr_policy = ContentSecurityPolicy::Create(); attr_policy->AddPolicyFromHeaderValue(attr, kContentSecurityPolicyHeaderTypeEnforce, diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc index e25bfc9de4b1..495b4e4ad502 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc @@ -1348,6 +1348,34 @@ TEST_F(ContentSecurityPolicyTest, IsValidCSPAttrTest) { "report-to relative-path/reporting;" "base-uri http://example.com 'self'", "")); + + // CRLF should not be allowed + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "base-uri\nhttp://example.com", "")); + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "base-uri http://example.com\nhttp://example2.com", "")); + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "base\n-uri http://example.com", "")); + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "\nbase-uri http://example.com", "")); + + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "base-uri\r\nhttp://example.com", "")); + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "base-uri http://example.com\r\nhttp://example2.com", "")); + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "base\r\n-uri http://example.com", "")); + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "\r\nbase-uri http://example.com", "")); + + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "base-uri\rhttp://example.com", "")); + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "base-uri http://example.com\rhttp://example2.com", "")); + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "base\r-uri http://example.com", "")); + EXPECT_FALSE(ContentSecurityPolicy::IsValidCSPAttr( + "\rbase-uri http://example.com", "")); } } // namespace blink