| Index: Source/core/frame/csp/CSPDirectiveList.cpp
|
| diff --git a/Source/core/frame/csp/CSPDirectiveList.cpp b/Source/core/frame/csp/CSPDirectiveList.cpp
|
| index e7dbb996d57cd1090d3233ed4aafc458d2a35e19..0cdc8305a4f11958d8f40afa97c68c7f2f7a9c1b 100644
|
| --- a/Source/core/frame/csp/CSPDirectiveList.cpp
|
| +++ b/Source/core/frame/csp/CSPDirectiveList.cpp
|
| @@ -43,7 +43,8 @@ CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurit
|
| , m_headerType(type)
|
| , m_headerSource(source)
|
| , m_reportOnly(false)
|
| - , m_haveSandboxPolicy(false)
|
| + , m_hasSandboxPolicy(false)
|
| + , m_hasSuboriginPolicy(false)
|
| , m_reflectedXSSDisposition(ReflectedXSSUnset)
|
| , m_didSetReferrerPolicy(false)
|
| , m_referrerPolicy(ReferrerPolicyDefault)
|
| @@ -532,11 +533,11 @@ void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sand
|
| m_policy->reportInvalidInReportOnly(name);
|
| return;
|
| }
|
| - if (m_haveSandboxPolicy) {
|
| + if (m_hasSandboxPolicy) {
|
| m_policy->reportDuplicateDirective(name);
|
| return;
|
| }
|
| - m_haveSandboxPolicy = true;
|
| + m_hasSandboxPolicy = true;
|
| String invalidTokens;
|
| m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidTokens));
|
| if (!invalidTokens.isNull())
|
| @@ -576,6 +577,24 @@ void CSPDirectiveList::enableInsecureRequestsUpgrade(const String& name, const S
|
| m_policy->reportValueForEmptyDirective(name, value);
|
| }
|
|
|
| +void CSPDirectiveList::applySuboriginPolicy(const String& name, const String& suboriginPolicy)
|
| +{
|
| + ASSERT(RuntimeEnabledFeatures::suboriginsEnabled());
|
| + if (m_headerSource == ContentSecurityPolicyHeaderSourceMeta) {
|
| + m_policy->reportSuboriginInMeta(suboriginPolicy);
|
| + return;
|
| + }
|
| +
|
| + if (m_hasSuboriginPolicy) {
|
| + m_policy->reportDuplicateDirective(name);
|
| + return;
|
| + }
|
| + m_hasSuboriginPolicy = true;
|
| + String suboriginName = parseSuboriginName(suboriginPolicy);
|
| + if (!suboriginName.isNull())
|
| + m_policy->enforceSuborigin(suboriginName);
|
| +}
|
| +
|
| void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value)
|
| {
|
| if (m_reflectedXSSDisposition != ReflectedXSSUnset) {
|
| @@ -676,7 +695,38 @@ void CSPDirectiveList::parseReferrer(const String& name, const String& value)
|
| // ^
|
| m_referrerPolicy = ReferrerPolicyNever;
|
| m_policy->reportInvalidReferrer(value);
|
| +}
|
| +
|
| +String CSPDirectiveList::parseSuboriginName(const String& policy)
|
| +{
|
| + Vector<UChar> characters;
|
| + policy.appendTo(characters);
|
| +
|
| + const UChar* position = characters.data();
|
| + const UChar* end = position + characters.size();
|
| +
|
| + // Parse the name of the suborigin (no spaces, single string)
|
| + skipWhile<UChar, isASCIISpace>(position, end);
|
| + if (position == end) {
|
| + m_policy->reportInvalidSuboriginFlags("No suborigin name specified.");
|
| + return String();
|
| + }
|
| +
|
| + const UChar* begin = position;
|
| +
|
| + skipWhile<UChar, isASCIIAlphanumeric>(position, end);
|
| + if (position != end && !isASCIISpace(*position)) {
|
| + m_policy->reportInvalidSuboriginFlags("Invalid character \'" + String(position, 1) + "\' in suborigin.");
|
| + return String();
|
| + }
|
| + size_t length = position - begin;
|
| + skipWhile<UChar, isASCIISpace>(position, end);
|
| + if (position != end) {
|
| + m_policy->reportInvalidSuboriginFlags("Whitespace is not allowed in suborigin names.");
|
| + return String();
|
| + }
|
|
|
| + return String(begin, length);
|
| }
|
|
|
| void CSPDirectiveList::addDirective(const String& name, const String& value)
|
| @@ -721,6 +771,8 @@ void CSPDirectiveList::addDirective(const String& name, const String& value)
|
| parseReflectedXSS(name, value);
|
| } else if (equalIgnoringCase(name, ContentSecurityPolicy::Referrer)) {
|
| parseReferrer(name, value);
|
| + } else if (RuntimeEnabledFeatures::suboriginsEnabled() && equalIgnoringCase(name, ContentSecurityPolicy::Suborigin)) {
|
| + applySuboriginPolicy(name, value);
|
| } else if (m_policy->experimentalFeaturesEnabled()) {
|
| if (equalIgnoringCase(name, ContentSecurityPolicy::ManifestSrc))
|
| setCSPDirective<SourceListDirective>(name, value, m_manifestSrc);
|
|
|