Commit 0f15bf84 authored by Antonio Sartori's avatar Antonio Sartori Committed by Commit Bot

Send CSP frame-ancestors violations also when XFO is present

If a Content-Security-Policy frame-ancestors directive is enforced,
then the X-Frame-Options header is ignored. However, if the
frame-ancestors directive is report-only, the X-Frame-Options header
is checked and the frame possibly blocked. However, in this second
case, we must still check whether we have to send a
Content-Security-Policy violation report.

Bug: 1097078
Change-Id: I9768a3859184ac1d35bd938f45cc40e111e2af4b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2339115Reviewed-by: default avatarArthur Sonzogni <arthursonzogni@chromium.org>
Commit-Queue: Antonio Sartori <antoniosartori@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795022}
parent da7e03d6
...@@ -188,24 +188,24 @@ NavigationThrottle::ThrottleCheckResult AncestorThrottle::ProcessResponseImpl( ...@@ -188,24 +188,24 @@ NavigationThrottle::ThrottleCheckResult AncestorThrottle::ProcessResponseImpl(
return NavigationThrottle::PROCEED; return NavigationThrottle::PROCEED;
} }
if (EvaluateXFrameOptions(logging) == CheckResult::BLOCK) {
return NavigationThrottle::BLOCK_RESPONSE;
}
// X-Frame-Option is checked on both redirect and final responses. However,
// CSP:Frame-ancestor is checked only for the final response.
if (!is_response_check)
return NavigationThrottle::PROCEED;
const std::vector<network::mojom::ContentSecurityPolicyPtr>& const std::vector<network::mojom::ContentSecurityPolicyPtr>&
content_security_policies = content_security_policies =
request->response()->parsed_headers->content_security_policy; request->response()->parsed_headers->content_security_policy;
if (EvaluateFrameAncestors(content_security_policies) == CheckResult::BLOCK) // CSP: frame-ancestors is checked only for the final response.
if (is_response_check &&
EvaluateFrameAncestors(content_security_policies) == CheckResult::BLOCK) {
return NavigationThrottle::BLOCK_RESPONSE;
}
if (EvaluateXFrameOptions(logging) == CheckResult::BLOCK)
return NavigationThrottle::BLOCK_RESPONSE; return NavigationThrottle::BLOCK_RESPONSE;
if (EvaluateCSPEmbeddedEnforcement() == CheckResult::BLOCK) // CSPEE is checked only for the final response.
if (is_response_check &&
EvaluateCSPEmbeddedEnforcement() == CheckResult::BLOCK) {
return NavigationThrottle::BLOCK_RESPONSE; return NavigationThrottle::BLOCK_RESPONSE;
}
return NavigationThrottle::PROCEED; return NavigationThrottle::PROCEED;
} }
......
<!DOCTYPE html>
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<title>Reporting works with report-only frame-ancestors even if frame is blocked by X-Frame-Options</title>
</head>
<body>
<iframe src="./support/not-embeddable-frame.py?reportID={{$id:uuid()}}&reportOnly=true&xFrameOptions=DENY"></iframe>
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=frame-ancestors&reportID={{$id}}'></script>
</body>
</html>
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<title>Reporting works with frame-ancestors</title> <title>Reporting works with frame-ancestors</title>
</head> </head>
<body> <body>
<iframe src="./support/not-embeddable-frame.html?reportID={{$id:uuid()}}"></iframe> <iframe src="./support/not-embeddable-frame.py?reportID={{$id:uuid()}}"></iframe>
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=frame-ancestors&reportID={{$id}}'></script> <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=frame-ancestors&reportID={{$id}}'></script>
</body> </body>
</html> </html>
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0, false
Pragma: no-cache
Content-Security-Policy: frame-ancestors 'none'; report-uri ../../support/report.py?op=put&reportID={{GET[reportID]}}
\ No newline at end of file
def main(request, response):
headers = []
if request.GET.first(b'xFrameOptions', None):
headers.append((b'X-Frame-Options', request.GET[b'xFrameOptions']))
csp_header = b'Content-Security-Policy-Report-Only' \
if request.GET.first(b'reportOnly', None) == 'true' else b'Content-Security-Policy'
headers.append((csp_header, b"frame-ancestors 'none'; report-uri ../../support/report.py?op=put&reportID=" + request.GET[b'reportID']))
return headers, b'{}'
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment