Commit 0ac2f509 authored by mkwst@chromium.org's avatar mkwst@chromium.org

CSP: Separate side-effects of parsing from the parsing code.

This patch shouldn't have any practical effect on CSP, but it will make
it straightforward to separate side-effects from parsing in a future
patch.

BUG=411889

Review URL: https://codereview.chromium.org/550223002

git-svn-id: svn://svn.chromium.org/blink/trunk@181632 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 742f5c21
...@@ -136,8 +136,28 @@ ContentSecurityPolicy::ContentSecurityPolicy(ExecutionContext* executionContext) ...@@ -136,8 +136,28 @@ ContentSecurityPolicy::ContentSecurityPolicy(ExecutionContext* executionContext)
, m_overrideInlineStyleAllowed(false) , m_overrideInlineStyleAllowed(false)
, m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone)
, m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone)
, m_sandboxMask(0)
, m_referrerPolicy(ReferrerPolicyDefault)
{ {
}
void ContentSecurityPolicy::applyPolicySideEffectsToExecutionContext()
{
// Ensure that 'self' processes correctly.
m_selfSource = adoptPtr(new CSPSource(this, securityOrigin()->protocol(), securityOrigin()->host(), securityOrigin()->port(), String(), false, false)); m_selfSource = adoptPtr(new CSPSource(this, securityOrigin()->protocol(), securityOrigin()->host(), securityOrigin()->port(), String(), false, false));
// If we're in a Document, set the referrer policy and sandbox flags.
if (Document* document = this->document()) {
document->enforceSandboxFlags(m_sandboxMask);
if (didSetReferrerPolicy())
document->setReferrerPolicy(m_referrerPolicy);
}
// 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 (!m_disableEvalErrorMessage.isNull())
executionContext()->disableEval(m_disableEvalErrorMessage);
} }
ContentSecurityPolicy::~ContentSecurityPolicy() ContentSecurityPolicy::~ContentSecurityPolicy()
...@@ -154,19 +174,29 @@ void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other) ...@@ -154,19 +174,29 @@ void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other)
ASSERT(m_policies.isEmpty()); ASSERT(m_policies.isEmpty());
for (CSPDirectiveListVector::const_iterator iter = other->m_policies.begin(); iter != other->m_policies.end(); ++iter) for (CSPDirectiveListVector::const_iterator iter = other->m_policies.begin(); iter != other->m_policies.end(); ++iter)
addPolicyFromHeaderValue((*iter)->header(), (*iter)->headerType(), (*iter)->headerSource()); addPolicyFromHeaderValue((*iter)->header(), (*iter)->headerType(), (*iter)->headerSource());
// FIXME: This ought to be a step distinct from copyStateFrom(). https://crbug.com/411889
applyPolicySideEffectsToExecutionContext();
} }
void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyResponseHeaders& headers) void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyResponseHeaders& headers)
{ {
if (!headers.contentSecurityPolicy().isEmpty()) if (!headers.contentSecurityPolicy().isEmpty())
didReceiveHeader(headers.contentSecurityPolicy(), ContentSecurityPolicyHeaderTypeEnforce, ContentSecurityPolicyHeaderSourceHTTP); didReceiveHeader(headers.contentSecurityPolicy(), ContentSecurityPolicyHeaderTypeEnforce, ContentSecurityPolicyHeaderSourceHTTP, DoNotApplySideEffectsToExecutionContext);
if (!headers.contentSecurityPolicyReportOnly().isEmpty()) if (!headers.contentSecurityPolicyReportOnly().isEmpty())
didReceiveHeader(headers.contentSecurityPolicyReportOnly(), ContentSecurityPolicyHeaderTypeReport, ContentSecurityPolicyHeaderSourceHTTP); didReceiveHeader(headers.contentSecurityPolicyReportOnly(), ContentSecurityPolicyHeaderTypeReport, ContentSecurityPolicyHeaderSourceHTTP, DoNotApplySideEffectsToExecutionContext);
// FIXME: This ought to be a step distinct from didReceiveHeaders(). https://crbug.com/411889
applyPolicySideEffectsToExecutionContext();
} }
void ContentSecurityPolicy::didReceiveHeader(const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source) void ContentSecurityPolicy::didReceiveHeader(const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source, SideEffectDisposition sideEffectDisposition)
{ {
addPolicyFromHeaderValue(header, type, source); addPolicyFromHeaderValue(header, type, source);
// FIXME: This ought to be a step distinct from didReceiveHeader(). https://crbug.com/411889
if (sideEffectDisposition == ApplySideEffectsToExecutionContext)
applyPolicySideEffectsToExecutionContext();
} }
void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source) void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
...@@ -185,7 +215,6 @@ void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, Conte ...@@ -185,7 +215,6 @@ void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, Conte
} }
} }
Vector<UChar> characters; Vector<UChar> characters;
header.appendTo(characters); header.appendTo(characters);
...@@ -203,9 +232,13 @@ void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, Conte ...@@ -203,9 +232,13 @@ void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, Conte
// ^ ^ // ^ ^
OwnPtr<CSPDirectiveList> policy = CSPDirectiveList::create(this, begin, position, type, source); 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 (type != ContentSecurityPolicyHeaderTypeReport && policy->didSetReferrerPolicy()) {
if (!policy->allowEval(0, SuppressReport)) // FIXME: We need a 'ReferrerPolicyUnset' enum to avoid confusing code like this.
m_executionContext->disableEval(policy->evalDisabledErrorMessage()); m_referrerPolicy = didSetReferrerPolicy() ? mergeReferrerPolicies(m_referrerPolicy, policy->referrerPolicy()) : policy->referrerPolicy();
}
if (!policy->allowEval(0, SuppressReport) && m_disableEvalErrorMessage.isNull())
m_disableEvalErrorMessage = policy->evalDisabledErrorMessage();
m_policies.append(policy.release()); m_policies.append(policy.release());
...@@ -214,9 +247,6 @@ void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, Conte ...@@ -214,9 +247,6 @@ void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, Conte
skipExactly<UChar>(position, end, ','); skipExactly<UChar>(position, end, ',');
begin = position; begin = position;
} }
if (document && type != ContentSecurityPolicyHeaderTypeReport && didSetReferrerPolicy())
document->setReferrerPolicy(referrerPolicy());
} }
void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value) void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value)
...@@ -546,10 +576,9 @@ KURL ContentSecurityPolicy::completeURL(const String& url) const ...@@ -546,10 +576,9 @@ KURL ContentSecurityPolicy::completeURL(const String& url) const
return m_executionContext->contextCompleteURL(url); return m_executionContext->contextCompleteURL(url);
} }
void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) const void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask)
{ {
if (Document* document = this->document()) m_sandboxMask |= mask;
document->enforceSandboxFlags(mask);
} }
static String stripURLForUseInReport(Document* document, const KURL& url) static String stripURLForUseInReport(Document* document, const KURL& url)
......
...@@ -84,6 +84,16 @@ public: ...@@ -84,6 +84,16 @@ public:
static const char ReflectedXSS[]; static const char ReflectedXSS[];
static const char Referrer[]; static const char Referrer[];
enum ReportingStatus {
SendReport,
SuppressReport
};
enum SideEffectDisposition {
ApplySideEffectsToExecutionContext,
DoNotApplySideEffectsToExecutionContext
};
static PassRefPtr<ContentSecurityPolicy> create(ExecutionContext* executionContext) static PassRefPtr<ContentSecurityPolicy> create(ExecutionContext* executionContext)
{ {
return adoptRef(new ContentSecurityPolicy(executionContext)); return adoptRef(new ContentSecurityPolicy(executionContext));
...@@ -92,13 +102,8 @@ public: ...@@ -92,13 +102,8 @@ public:
void copyStateFrom(const ContentSecurityPolicy*); void copyStateFrom(const ContentSecurityPolicy*);
enum ReportingStatus {
SendReport,
SuppressReport
};
void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&); void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&);
void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource); void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource, SideEffectDisposition = ApplySideEffectsToExecutionContext);
// These functions are wrong because they assume that there is only one header. // These functions are wrong because they assume that there is only one header.
// FIXME: Replace them with functions that return vectors. // FIXME: Replace them with functions that return vectors.
...@@ -169,7 +174,7 @@ public: ...@@ -169,7 +174,7 @@ public:
const KURL url() const; const KURL url() const;
KURL completeURL(const String&) const; KURL completeURL(const String&) const;
void enforceSandboxFlags(SandboxFlags) const; void enforceSandboxFlags(SandboxFlags);
String evalDisabledErrorMessage() const; String evalDisabledErrorMessage() const;
bool urlMatchesSelf(const KURL&) const; bool urlMatchesSelf(const KURL&) const;
...@@ -186,6 +191,8 @@ public: ...@@ -186,6 +191,8 @@ public:
private: private:
explicit ContentSecurityPolicy(ExecutionContext*); explicit ContentSecurityPolicy(ExecutionContext*);
void applyPolicySideEffectsToExecutionContext();
Document* document() const; Document* document() const;
SecurityOrigin* securityOrigin() const; SecurityOrigin* securityOrigin() const;
...@@ -207,6 +214,11 @@ private: ...@@ -207,6 +214,11 @@ private:
uint8_t m_scriptHashAlgorithmsUsed; uint8_t m_scriptHashAlgorithmsUsed;
uint8_t m_styleHashAlgorithmsUsed; uint8_t m_styleHashAlgorithmsUsed;
// State flags used to configure the environment after parsing a policy.
SandboxFlags m_sandboxMask;
ReferrerPolicy m_referrerPolicy;
String m_disableEvalErrorMessage;
OwnPtr<CSPSource> m_selfSource; OwnPtr<CSPSource> m_selfSource;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment