| Index: third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| index 92920a39a22e4302c5a619b9b72cad197a7ebace..492e74575f3980a0ee6156e659baf3b39a7742ad 100644
|
| --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| @@ -29,6 +29,7 @@
|
| #include "bindings/core/v8/SourceLocation.h"
|
| #include "core/dom/DOMStringList.h"
|
| #include "core/dom/Document.h"
|
| +#include "core/dom/Element.h"
|
| #include "core/dom/SandboxFlags.h"
|
| #include "core/events/SecurityPolicyViolationEvent.h"
|
| #include "core/fetch/IntegrityMetadata.h"
|
| @@ -60,6 +61,7 @@
|
| #include "public/platform/Platform.h"
|
| #include "public/platform/WebAddressSpace.h"
|
| #include "public/platform/WebURLRequest.h"
|
| +#include "wtf/NotFound.h"
|
| #include "wtf/PtrUtil.h"
|
| #include "wtf/StringHasher.h"
|
| #include "wtf/text/ParsingUtilities.h"
|
| @@ -135,6 +137,38 @@ bool ContentSecurityPolicy::isDirectiveName(const String& name)
|
| || equalIgnoringCase(name, RequireSRIFor));
|
| }
|
|
|
| +bool ContentSecurityPolicy::isNonceableElement(const Element* element)
|
| +{
|
| + if (!element->fastHasAttribute(HTMLNames::nonceAttr))
|
| + return false;
|
| +
|
| + bool nonceable = true;
|
| +
|
| + // To prevent an attacker from hijacking an existing nonce via a dangling markup injection,
|
| + // we walk through the attributes of each nonced script element: if their names or values
|
| + // contain "<script" or "<style", we won't apply the nonce when loading script.
|
| + //
|
| + // See http://blog.innerht.ml/csp-2015/#danglingmarkupinjection for an example of the kind
|
| + // of attack this is aimed at mitigating.
|
| + DEFINE_STATIC_LOCAL(AtomicString, scriptString, ("<script"));
|
| + DEFINE_STATIC_LOCAL(AtomicString, styleString, ("<style"));
|
| + for (const Attribute& attr : element->attributes()) {
|
| + AtomicString name = attr.localName().lowerASCII();
|
| + AtomicString value = attr.value().lowerASCII();
|
| + if (name.find(scriptString) != WTF::kNotFound || name.find(styleString) != WTF::kNotFound
|
| + || value.find(scriptString) != WTF::kNotFound || value.find(styleString) != WTF::kNotFound) {
|
| + nonceable = false;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + UseCounter::count(element->document(), nonceable ? UseCounter::CleanScriptElementWithNonce : UseCounter::PotentiallyInjectedScriptElementWithNonce);
|
| +
|
| + // This behavior is locked behind the experimental flag for the moment; if we
|
| + // decide to ship it, drop this check. https://crbug.com/639293
|
| + return !RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnabled() || nonceable;
|
| +}
|
| +
|
| static UseCounter::Feature getUseCounterType(ContentSecurityPolicyHeaderType type)
|
| {
|
| switch (type) {
|
|
|