Index: third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp |
diff --git a/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp b/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp |
index 6449cf9579a44c5258469eff9f25375582c74873..9b00a3a9e96eeb22594921ad171da3d3a909d363 100644 |
--- a/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp |
+++ b/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp |
@@ -617,6 +617,8 @@ bool SourceListDirective::subsumes( |
bool allowDynamicOther = other[0]->m_allowDynamic; |
bool allowHashedAttributesOther = other[0]->m_allowHashedAttributes; |
bool isHashOrNoncePresentOther = other[0]->isHashOrNoncePresent(); |
+ HashSet<String> noncesB = other[0]->m_nonces; |
+ HashSet<CSPHashValue> hashesB = other[0]->m_hashes; |
for (size_t i = 1; i < other.size(); i++) { |
allowInlineOther = allowInlineOther && other[i]->m_allowInline; |
@@ -626,9 +628,14 @@ bool SourceListDirective::subsumes( |
allowHashedAttributesOther && other[i]->m_allowHashedAttributes; |
isHashOrNoncePresentOther = |
isHashOrNoncePresentOther && other[i]->isHashOrNoncePresent(); |
+ noncesB = other[i]->getIntersectNonces(noncesB); |
+ hashesB = other[i]->getIntersectHashes(hashesB); |
normalizedB = other[i]->getIntersectCSPSources(normalizedB); |
} |
+ if (!subsumesNoncesAndHashes(noncesB, hashesB)) |
+ return false; |
+ |
const ContentSecurityPolicy::DirectiveType type = |
ContentSecurityPolicy::getDirectiveType(m_directiveName); |
if (type == ContentSecurityPolicy::DirectiveType::ScriptSrc || |
@@ -648,6 +655,49 @@ bool SourceListDirective::subsumes( |
return CSPSource::firstSubsumesSecond(normalizedA, normalizedB); |
} |
+bool SourceListDirective::subsumesNoncesAndHashes( |
+ const HashSet<String>& nonces, |
+ const HashSet<CSPHashValue> hashes) { |
+ for (const auto& nonce : nonces) { |
+ if (!m_nonces.contains(nonce)) |
+ return false; |
+ } |
+ for (const auto& hash : hashes) { |
+ if (!m_hashes.contains(hash)) |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+HashSet<String> SourceListDirective::getIntersectNonces( |
+ const HashSet<String>& other) { |
+ if (!m_nonces.size() || !other.size()) |
+ return !m_nonces.size() ? m_nonces : other; |
+ |
+ HashSet<String> normalized; |
+ for (const auto& nonce : m_nonces) { |
+ if (other.contains(nonce)) |
+ normalized.add(nonce); |
+ } |
+ |
+ return normalized; |
+} |
+ |
+HashSet<CSPHashValue> SourceListDirective::getIntersectHashes( |
+ const HashSet<CSPHashValue>& other) { |
+ if (!m_hashes.size() || !other.size()) |
+ return !m_hashes.size() ? m_hashes : other; |
+ |
+ HashSet<CSPHashValue> normalized; |
+ for (const auto& hash : m_hashes) { |
+ if (other.contains(hash)) |
+ normalized.add(hash); |
+ } |
+ |
+ return normalized; |
+} |
+ |
HashMap<String, CSPSource*> SourceListDirective::getIntersectSchemesOnly( |
HeapVector<Member<CSPSource>> other) { |
HashMap<String, CSPSource*> schemesA; |