Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(619)

Unified Diff: Source/core/frame/ContentSecurityPolicy.cpp

Issue 91353002: CSP 1.1: Implement the 'frame-ancestors' directive. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/frame/ContentSecurityPolicy.h ('k') | Source/core/loader/FrameLoader.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/frame/ContentSecurityPolicy.cpp
diff --git a/Source/core/frame/ContentSecurityPolicy.cpp b/Source/core/frame/ContentSecurityPolicy.cpp
index e4b9eb18c21379dec8d909be260a627ac9d22e7e..dbcd2d3d318896d52ed07ba3d47d5d75506f6faf 100644
--- a/Source/core/frame/ContentSecurityPolicy.cpp
+++ b/Source/core/frame/ContentSecurityPolicy.cpp
@@ -149,6 +149,7 @@ static const char styleSrc[] = "style-src";
// CSP 1.1 Directives
static const char baseURI[] = "base-uri";
static const char formAction[] = "form-action";
+static const char frameAncestors[] = "frame-ancestors";
static const char pluginTypes[] = "plugin-types";
static const char reflectedXSS[] = "reflected-xss";
static const char referrer[] = "referrer";
@@ -168,6 +169,7 @@ bool isDirectiveName(const String& name)
|| equalIgnoringCase(name, styleSrc)
|| equalIgnoringCase(name, baseURI)
|| equalIgnoringCase(name, formAction)
+ || equalIgnoringCase(name, frameAncestors)
|| equalIgnoringCase(name, pluginTypes)
|| equalIgnoringCase(name, reflectedXSS)
|| equalIgnoringCase(name, referrer)
@@ -893,6 +895,7 @@ public:
bool allowConnectToSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
bool allowFormAction(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
bool allowBaseURI(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowAncestors(Frame*, ContentSecurityPolicy::ReportingStatus) const;
bool allowScriptNonce(const String&) const;
bool allowStyleNonce(const String&) const;
bool allowScriptHash(const SourceHashValue&) const;
@@ -930,6 +933,7 @@ private:
bool checkHash(SourceListDirective*, const SourceHashValue&) const;
bool checkSource(SourceListDirective*, const KURL&) const;
bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const;
+ bool checkAncestors(SourceListDirective*, Frame*) const;
void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; }
@@ -938,6 +942,7 @@ private:
bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& effectiveDirective) const;
bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& type, const String& typeAttribute, const String& consoleMessage) const;
+ bool checkAncestorsAndReportViolation(SourceListDirective*, Frame*) const;
bool denyIfEnforcingPolicy() const { return m_reportOnly; }
@@ -960,6 +965,7 @@ private:
OwnPtr<SourceListDirective> m_defaultSrc;
OwnPtr<SourceListDirective> m_fontSrc;
OwnPtr<SourceListDirective> m_formAction;
+ OwnPtr<SourceListDirective> m_frameAncestors;
OwnPtr<SourceListDirective> m_frameSrc;
OwnPtr<SourceListDirective> m_imgSrc;
OwnPtr<SourceListDirective> m_mediaSrc;
@@ -1047,6 +1053,18 @@ bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& u
return !directive || directive->allows(url);
}
+bool CSPDirectiveList::checkAncestors(SourceListDirective* directive, Frame* frame) const
+{
+ if (!frame || !directive)
+ return true;
+
+ for (Frame* current = frame->tree().parent(); current; current = current->tree().parent()) {
+ if (!directive->allows(current->document()->url()))
+ return false;
+ }
+ return true;
+}
+
bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
{
if (!directive)
@@ -1151,6 +1169,15 @@ bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* direct
return denyIfEnforcingPolicy();
}
+bool CSPDirectiveList::checkAncestorsAndReportViolation(SourceListDirective* directive, Frame* frame) const
+{
+ if (checkAncestors(directive, frame))
+ return true;
+
+ reportViolation(directive->text(), "frame-ancestors", "Refused to display '" + frame->document()->url().elidedString() + " in a frame because an ancestor violates the following Content Security Policy directive: \"" + directive->text() + "\".", frame->document()->url());
+ return denyIfEnforcingPolicy();
+}
+
bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
{
DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "));
@@ -1274,6 +1301,13 @@ bool CSPDirectiveList::allowBaseURI(const KURL& url, ContentSecurityPolicy::Repo
checkSource(m_baseURI.get(), url);
}
+bool CSPDirectiveList::allowAncestors(Frame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkAncestorsAndReportViolation(m_frameAncestors.get(), frame) :
+ checkAncestors(m_frameAncestors.get(), frame);
+}
+
bool CSPDirectiveList::allowScriptNonce(const String& nonce) const
{
return checkNonce(operativeDirective(m_scriptSrc.get()), nonce);
@@ -1563,6 +1597,8 @@ void CSPDirectiveList::addDirective(const String& name, const String& value)
setCSPDirective<SourceListDirective>(name, value, m_baseURI);
else if (equalIgnoringCase(name, formAction))
setCSPDirective<SourceListDirective>(name, value, m_formAction);
+ else if (equalIgnoringCase(name, frameAncestors))
+ setCSPDirective<SourceListDirective>(name, value, m_frameAncestors);
else if (equalIgnoringCase(name, pluginTypes))
setCSPDirective<MediaListDirective>(name, value, m_pluginTypes);
else if (equalIgnoringCase(name, reflectedXSS))
@@ -1746,6 +1782,16 @@ bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& u
return true;
}
+template<bool (CSPDirectiveList::*allowed)(Frame*, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, Frame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowed)(frame, reportingStatus))
+ return false;
+ }
+ return true;
+}
+
bool ContentSecurityPolicy::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
{
return isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(m_policies, contextURL, contextLine, reportingStatus);
@@ -1894,6 +1940,11 @@ bool ContentSecurityPolicy::allowBaseURI(const KURL& url, ContentSecurityPolicy:
return isAllowedByAllWithURL<&CSPDirectiveList::allowBaseURI>(m_policies, url, reportingStatus);
}
+bool ContentSecurityPolicy::allowAncestors(Frame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithFrame<&CSPDirectiveList::allowAncestors>(m_policies, frame, reportingStatus);
+}
+
bool ContentSecurityPolicy::isActive() const
{
return !m_policies.isEmpty();
« no previous file with comments | « Source/core/frame/ContentSecurityPolicy.h ('k') | Source/core/loader/FrameLoader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698