| Index: Source/core/frame/ContentSecurityPolicy.cpp
|
| diff --git a/Source/core/frame/ContentSecurityPolicy.cpp b/Source/core/frame/ContentSecurityPolicy.cpp
|
| index 2c92383d5100dd9152ac31be0649955fdd203e9a..cd2ba576fda89e814dd1b9458351f436b68e4208 100644
|
| --- a/Source/core/frame/ContentSecurityPolicy.cpp
|
| +++ b/Source/core/frame/ContentSecurityPolicy.cpp
|
| @@ -868,12 +868,13 @@ private:
|
| class CSPDirectiveList {
|
| WTF_MAKE_FAST_ALLOCATED;
|
| public:
|
| - static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UChar* begin, const UChar* end, ContentSecurityPolicy::HeaderType);
|
| + static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UChar* begin, const UChar* end, ContentSecurityPolicy::HeaderType, ContentSecurityPolicy::HeaderSource);
|
|
|
| void parse(const UChar* begin, const UChar* end);
|
|
|
| const String& header() const { return m_header; }
|
| ContentSecurityPolicy::HeaderType headerType() const { return m_headerType; }
|
| + ContentSecurityPolicy::HeaderSource headerSource() const { return m_headerSource; }
|
|
|
| bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
|
| bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
|
| @@ -905,7 +906,7 @@ public:
|
| const Vector<KURL>& reportURIs() const { return m_reportURIs; }
|
|
|
| private:
|
| - CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicy::HeaderType);
|
| + CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicy::HeaderType, ContentSecurityPolicy::HeaderSource);
|
|
|
| bool parseDirective(const UChar* begin, const UChar* end, String& name, String& value);
|
| void parseReportURI(const String& name, const String& value);
|
| @@ -944,6 +945,7 @@ private:
|
|
|
| String m_header;
|
| ContentSecurityPolicy::HeaderType m_headerType;
|
| + ContentSecurityPolicy::HeaderSource m_headerSource;
|
|
|
| bool m_reportOnly;
|
| bool m_haveSandboxPolicy;
|
| @@ -970,9 +972,10 @@ private:
|
| String m_evalDisabledErrorMessage;
|
| };
|
|
|
| -CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicy::HeaderType type)
|
| +CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicy::HeaderType type, ContentSecurityPolicy::HeaderSource source)
|
| : m_policy(policy)
|
| , m_headerType(type)
|
| + , m_headerSource(source)
|
| , m_reportOnly(false)
|
| , m_haveSandboxPolicy(false)
|
| , m_reflectedXSSDisposition(ReflectedXSSUnset)
|
| @@ -982,9 +985,9 @@ CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurit
|
| m_reportOnly = type == ContentSecurityPolicy::Report;
|
| }
|
|
|
| -PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const UChar* begin, const UChar* end, ContentSecurityPolicy::HeaderType type)
|
| +PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const UChar* begin, const UChar* end, ContentSecurityPolicy::HeaderType type, ContentSecurityPolicy::HeaderSource source)
|
| {
|
| - OwnPtr<CSPDirectiveList> directives = adoptPtr(new CSPDirectiveList(policy, type));
|
| + OwnPtr<CSPDirectiveList> directives = adoptPtr(new CSPDirectiveList(policy, type, source));
|
| directives->parse(begin, end);
|
|
|
| if (!directives->checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
|
| @@ -1587,15 +1590,15 @@ void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other)
|
| {
|
| ASSERT(m_policies.isEmpty());
|
| for (CSPDirectiveListVector::const_iterator iter = other->m_policies.begin(); iter != other->m_policies.end(); ++iter)
|
| - addPolicyFromHeaderValue((*iter)->header(), (*iter)->headerType());
|
| + addPolicyFromHeaderValue((*iter)->header(), (*iter)->headerType(), (*iter)->headerSource());
|
| }
|
|
|
| void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyResponseHeaders& headers)
|
| {
|
| if (!headers.contentSecurityPolicy().isEmpty())
|
| - didReceiveHeader(headers.contentSecurityPolicy(), ContentSecurityPolicy::Enforce);
|
| + didReceiveHeader(headers.contentSecurityPolicy(), ContentSecurityPolicy::Enforce, ContentSecurityPolicy::HeaderSourceHTTP);
|
| if (!headers.contentSecurityPolicyReportOnly().isEmpty())
|
| - didReceiveHeader(headers.contentSecurityPolicyReportOnly(), ContentSecurityPolicy::Report);
|
| + didReceiveHeader(headers.contentSecurityPolicyReportOnly(), ContentSecurityPolicy::Report, ContentSecurityPolicy::HeaderSourceHTTP);
|
|
|
| // FIXME: Remove this reporting (and the 'xWebKitCSP*' methods) after the next release branch.
|
| if (m_client->isDocument()) {
|
| @@ -1607,19 +1610,29 @@ void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyRespons
|
| }
|
| }
|
|
|
| -void ContentSecurityPolicy::didReceiveHeader(const String& header, HeaderType type)
|
| +void ContentSecurityPolicy::didReceiveHeader(const String& header, HeaderType type, HeaderSource source)
|
| {
|
| - addPolicyFromHeaderValue(header, type);
|
| + addPolicyFromHeaderValue(header, type, source);
|
| }
|
|
|
| -void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, HeaderType type)
|
| +void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, HeaderType type, HeaderSource source)
|
| {
|
| Document* document = 0;
|
| if (m_client->isDocument()) {
|
| document = static_cast<Document*>(m_client);
|
| UseCounter::count(*document, getUseCounterType(type));
|
| +
|
| + // CSP 1.1 defines report-only in a <meta> element as invalid. Measure for now, disable in experimental mode.
|
| + if (source == ContentSecurityPolicy::HeaderSourceMeta && type == ContentSecurityPolicy::Report) {
|
| + UseCounter::count(*document, UseCounter::ContentSecurityPolicyReportOnlyInMeta);
|
| + if (experimentalFeaturesEnabled()) {
|
| + reportReportOnlyInMeta(header);
|
| + return;
|
| + }
|
| + }
|
| }
|
|
|
| +
|
| Vector<UChar> characters;
|
| header.appendTo(characters);
|
|
|
| @@ -1635,7 +1648,7 @@ void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, Heade
|
|
|
| // header1,header2 OR header1
|
| // ^ ^
|
| - OwnPtr<CSPDirectiveList> policy = CSPDirectiveList::create(this, begin, position, type);
|
| + OwnPtr<CSPDirectiveList> policy = CSPDirectiveList::create(this, begin, position, type, source);
|
|
|
| // We disable 'eval()' even in the case of report-only policies, and rely on the check in the V8Initializer::codeGenerationCheckCallbackInMainThread callback to determine whether the call should execute or not.
|
| if (!policy->allowEval(0, SuppressReport))
|
| @@ -2043,6 +2056,11 @@ void ContentSecurityPolicy::reportInvalidReferrer(const String& invalidValue) co
|
| logToConsole("The 'referrer' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"always\", \"default\", \"never\", and \"origin\".");
|
| }
|
|
|
| +void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) const
|
| +{
|
| + logToConsole("The report-only Content Security Policy '" + header + "' was delivered via a <meta> element, which is disallowed. The policy has been ignored.");
|
| +}
|
| +
|
| void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name) const
|
| {
|
| logToConsole("The Content Security Policy directive '" + name + "' is ignored when delivered in a report-only policy.");
|
|
|