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

Unified Diff: third_party/WebKit/Source/core/frame/csp/CSPSource.cpp

Issue 2708873002: Stop CSP from matching independent scheme/port upgrades (Closed)
Patch Set: rebase-update Created 3 years, 9 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
Index: third_party/WebKit/Source/core/frame/csp/CSPSource.cpp
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp b/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp
index 511f666e5a6453515350a639059bed3149a7c318..d982d6a4d6aa6610a84a153f3ae5a62fe0fa1190 100644
--- a/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp
@@ -30,25 +30,48 @@ CSPSource::CSPSource(ContentSecurityPolicy* policy,
bool CSPSource::matches(const KURL& url,
ResourceRequest::RedirectStatus redirectStatus) const {
- bool schemesMatch = m_scheme.isEmpty() ? m_policy->protocolMatchesSelf(url)
- : schemeMatches(url.protocol());
- if (!schemesMatch)
+ SchemeMatchingResult schemesMatch = schemeMatches(url.protocol());
+ if (schemesMatch == SchemeMatchingResult::NotMatching)
return false;
if (isSchemeOnly())
return true;
bool pathsMatch = (redirectStatus == RedirectStatus::FollowedRedirect) ||
pathMatches(url.path());
- return hostMatches(url.host()) && portMatches(url.port(), url.protocol()) &&
- pathsMatch;
+ PortMatchingResult portsMatch = portMatches(url.port(), url.protocol());
+
+ // if either the scheme or the port would require an upgrade (e.g. from http
+ // to https) then check that both of them can upgrade to ensure that we don't
+ // run into situations where we only upgrade the port but not the scheme or
+ // viceversa
+ if ((requiresUpgrade(schemesMatch) || (requiresUpgrade(portsMatch))) &&
+ (!canUpgrade(schemesMatch) || !canUpgrade(portsMatch))) {
+ return false;
+ }
+
+ return hostMatches(url.host()) && portsMatch != PortMatchingResult::NotMatching && pathsMatch;
}
-bool CSPSource::schemeMatches(const String& protocol) const {
+CSPSource::SchemeMatchingResult CSPSource::schemeMatches(
+ const String& protocol) const {
DCHECK_EQ(protocol, protocol.lower());
- if (m_scheme == "http")
- return protocol == "http" || protocol == "https";
- if (m_scheme == "ws")
- return protocol == "ws" || protocol == "wss";
- return protocol == m_scheme;
+ const String& scheme =
+ (m_scheme.isEmpty() ? m_policy->getSelfProtocol() : m_scheme);
+
+ if (scheme == protocol)
+ return SchemeMatchingResult::MatchingExact;
+
+ if ((scheme == "http" && protocol == "https") ||
+ (scheme == "http" && protocol == "https-so") ||
+ (scheme == "ws" && protocol == "wss")) {
+ return SchemeMatchingResult::MatchingUpgrade;
+ }
+
+ if ((scheme == "http" && protocol == "http-so") ||
+ (scheme == "https" && protocol == "https-so")) {
+ return SchemeMatchingResult::MatchingExact;
+ }
+
+ return SchemeMatchingResult::NotMatching;
}
bool CSPSource::hostMatches(const String& host) const {
@@ -92,28 +115,45 @@ bool CSPSource::pathMatches(const String& urlPath) const {
return path == m_path;
}
-bool CSPSource::portMatches(int port, const String& protocol) const {
+CSPSource::PortMatchingResult CSPSource::portMatches(
+ int port,
+ const String& protocol) const {
if (m_portWildcard == HasWildcard)
- return true;
+ return PortMatchingResult::MatchingWildcard;
- if (port == m_port)
- return true;
+ if (port == m_port) {
+ if (port == 0)
+ return PortMatchingResult::MatchingWildcard;
+ return PortMatchingResult::MatchingExact;
+ }
+
+ bool isSchemeHttp; // needed for detecting an upgrade when the port is 0
+ isSchemeHttp = m_scheme.isEmpty() ? m_policy->protocolEqualsSelf("http")
+ : equalIgnoringCase("http", m_scheme);
- if (m_port == 80 &&
+ if ((m_port == 80 || (m_port == 0 && isSchemeHttp)) &&
(port == 443 || (port == 0 && defaultPortForProtocol(protocol) == 443)))
- return true;
+ return PortMatchingResult::MatchingUpgrade;
- if (!port)
- return isDefaultPortForProtocol(m_port, protocol);
+ if (!port) {
+ if (isDefaultPortForProtocol(m_port, protocol))
+ return PortMatchingResult::MatchingExact;
- if (!m_port)
- return isDefaultPortForProtocol(port, protocol);
+ return PortMatchingResult::NotMatching;
+ }
- return false;
+ if (!m_port) {
+ if (isDefaultPortForProtocol(port, protocol))
+ return PortMatchingResult::MatchingExact;
+
+ return PortMatchingResult::NotMatching;
+ }
+
+ return PortMatchingResult::NotMatching;
}
bool CSPSource::subsumes(CSPSource* other) const {
- if (!schemeMatches(other->m_scheme))
+ if (schemeMatches(other->m_scheme) == SchemeMatchingResult::NotMatching)
return false;
if (other->isSchemeOnly() || isSchemeOnly())
@@ -126,21 +166,22 @@ bool CSPSource::subsumes(CSPSource* other) const {
bool hostSubsumes = (m_host == other->m_host || hostMatches(other->m_host));
bool portSubsumes = (m_portWildcard == HasWildcard) ||
- portMatches(other->m_port, other->m_scheme);
+ portMatches(other->m_port, other->m_scheme) != PortMatchingResult::NotMatching;
bool pathSubsumes = pathMatches(other->m_path);
return hostSubsumes && portSubsumes && pathSubsumes;
}
bool CSPSource::isSimilar(CSPSource* other) const {
bool schemesMatch =
- schemeMatches(other->m_scheme) || other->schemeMatches(m_scheme);
+ schemeMatches(other->m_scheme) != SchemeMatchingResult::NotMatching
+ || other->schemeMatches(m_scheme) != SchemeMatchingResult::NotMatching;
if (!schemesMatch || isSchemeOnly() || other->isSchemeOnly())
return schemesMatch;
bool hostsMatch = (m_host == other->m_host) || hostMatches(other->m_host) ||
other->hostMatches(m_host);
bool portsMatch = (other->m_portWildcard == HasWildcard) ||
- portMatches(other->m_port, other->m_scheme) ||
- other->portMatches(m_port, m_scheme);
+ portMatches(other->m_port, other->m_scheme) != PortMatchingResult::NotMatching ||
+ other->portMatches(m_port, m_scheme) != PortMatchingResult::NotMatching;
bool pathsMatch = pathMatches(other->m_path) || other->pathMatches(m_path);
if (hostsMatch && portsMatch && pathsMatch)
return true;
@@ -152,7 +193,7 @@ CSPSource* CSPSource::intersect(CSPSource* other) const {
if (!isSimilar(other))
return nullptr;
- String scheme = other->schemeMatches(m_scheme) ? m_scheme : other->m_scheme;
+ String scheme = other->schemeMatches(m_scheme) != SchemeMatchingResult::NotMatching ? m_scheme : other->m_scheme;
if (isSchemeOnly() || other->isSchemeOnly()) {
const CSPSource* stricter = isSchemeOnly() ? other : this;
return new CSPSource(m_policy, scheme, stricter->m_host, stricter->m_port,
« no previous file with comments | « third_party/WebKit/Source/core/frame/csp/CSPSource.h ('k') | third_party/WebKit/Source/core/frame/csp/CSPSourceTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698