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

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

Issue 2708873002: Stop CSP from matching independent scheme/port upgrades (Closed)
Patch Set: Refactoring port/scheme matching logic to have an easier time with auto-upgrading Created 3 years, 10 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/frame/csp/CSPSource.h" 5 #include "core/frame/csp/CSPSource.h"
6 6
7 #include "core/frame/UseCounter.h" 7 #include "core/frame/UseCounter.h"
8 #include "core/frame/csp/ContentSecurityPolicy.h" 8 #include "core/frame/csp/ContentSecurityPolicy.h"
9 #include "platform/weborigin/KURL.h" 9 #include "platform/weborigin/KURL.h"
10 #include "platform/weborigin/KnownPorts.h" 10 #include "platform/weborigin/KnownPorts.h"
(...skipping 12 matching lines...) Expand all
23 : m_policy(policy), 23 : m_policy(policy),
24 m_scheme(scheme.lower()), 24 m_scheme(scheme.lower()),
25 m_host(host), 25 m_host(host),
26 m_port(port), 26 m_port(port),
27 m_path(path), 27 m_path(path),
28 m_hostWildcard(hostWildcard), 28 m_hostWildcard(hostWildcard),
29 m_portWildcard(portWildcard) {} 29 m_portWildcard(portWildcard) {}
30 30
31 bool CSPSource::matches(const KURL& url, 31 bool CSPSource::matches(const KURL& url,
32 ResourceRequest::RedirectStatus redirectStatus) const { 32 ResourceRequest::RedirectStatus redirectStatus) const {
33 bool schemesMatch = m_scheme.isEmpty() ? m_policy->protocolMatchesSelf(url) 33 SchemeMatchingResult schemesMatch = schemeMatches(url.protocol());
34 : schemeMatches(url.protocol());
35 if (!schemesMatch) 34 if (!schemesMatch)
36 return false; 35 return false;
37 if (isSchemeOnly()) 36 if (isSchemeOnly())
38 return true; 37 return true;
39 bool pathsMatch = (redirectStatus == RedirectStatus::FollowedRedirect) || 38 bool pathsMatch = (redirectStatus == RedirectStatus::FollowedRedirect) ||
40 pathMatches(url.path()); 39 pathMatches(url.path());
41 return hostMatches(url.host()) && portMatches(url.port(), url.protocol()) && 40 PortMatchingResult portsMatch = portMatches(url.port(), url.protocol());
42 pathsMatch; 41
42 // if either the scheme or the port would require an upgrade (e.g. from http
43 // to https) then check that both of them can upgrade to ensure that we don't
44 // run into situations where we only upgrade the port but not the scheme or
45 // viceversa
46 if ((requiresUpgrade(schemesMatch) || (requiresUpgrade(portsMatch))) &&
47 (!canUpgrade(schemesMatch) || !canUpgrade(portsMatch))) {
48 return false;
49 }
50
51 return hostMatches(url.host()) && portsMatch && pathsMatch;
43 } 52 }
44 53
45 bool CSPSource::schemeMatches(const String& protocol) const { 54 CSPSource::SchemeMatchingResult CSPSource::schemeMatches(
55 const String& protocol) const {
46 DCHECK_EQ(protocol, protocol.lower()); 56 DCHECK_EQ(protocol, protocol.lower());
47 if (m_scheme == "http") 57 const String& scheme =
48 return protocol == "http" || protocol == "https"; 58 (m_scheme.isEmpty() ? m_policy->getSelfProtocol() : m_scheme);
49 if (m_scheme == "ws") 59
50 return protocol == "ws" || protocol == "wss"; 60 if (scheme == protocol)
51 return protocol == m_scheme; 61 return SchemeMatchingExact;
62
63 if ((scheme == "http" && protocol == "https") ||
64 (scheme == "http" && protocol == "https-so") ||
65 (scheme == "ws" && protocol == "wss")) {
66 return SchemeMatchingUpgrade;
67 }
68
69 if ((scheme == "http" && protocol == "http-so") ||
70 (scheme == "https" && protocol == "https-so")) {
71 return SchemeMatchingExact;
72 }
73
74 return SchemeNotMatching;
52 } 75 }
53 76
54 bool CSPSource::hostMatches(const String& host) const { 77 bool CSPSource::hostMatches(const String& host) const {
55 Document* document = m_policy->document(); 78 Document* document = m_policy->document();
56 bool match; 79 bool match;
57 80
58 bool equalHosts = m_host == host; 81 bool equalHosts = m_host == host;
59 if (m_hostWildcard == HasWildcard) { 82 if (m_hostWildcard == HasWildcard) {
60 if (m_host.isEmpty()) { 83 if (m_host.isEmpty()) {
61 // host-part = "*" 84 // host-part = "*"
(...skipping 23 matching lines...) Expand all
85 return true; 108 return true;
86 109
87 String path = decodeURLEscapeSequences(urlPath); 110 String path = decodeURLEscapeSequences(urlPath);
88 111
89 if (m_path.endsWith("/")) 112 if (m_path.endsWith("/"))
90 return path.startsWith(m_path); 113 return path.startsWith(m_path);
91 114
92 return path == m_path; 115 return path == m_path;
93 } 116 }
94 117
95 bool CSPSource::portMatches(int port, const String& protocol) const { 118 CSPSource::PortMatchingResult CSPSource::portMatches(
119 int port,
120 const String& protocol) const {
96 if (m_portWildcard == HasWildcard) 121 if (m_portWildcard == HasWildcard)
97 return true; 122 return PortMatchingWildcard;
98 123
99 if (port == m_port) 124 if (port == m_port) {
100 return true; 125 if (port == 0)
126 return PortMatchingWildcard;
127 return PortMatchingExact;
128 }
101 129
102 if (m_port == 80 && 130 bool isSchemeHttp; // needed for detecting an upgrade when the port is 0
131 isSchemeHttp = m_scheme.isEmpty() ? m_policy->protocolEqualsSelf("http")
132 : equalIgnoringCase("http", m_scheme);
133
134 if ((m_port == 80 || (m_port == 0 && isSchemeHttp)) &&
103 (port == 443 || (port == 0 && defaultPortForProtocol(protocol) == 443))) 135 (port == 443 || (port == 0 && defaultPortForProtocol(protocol) == 443)))
104 return true; 136 return PortMatchingUpgrade;
105 137
106 if (!port) 138 if (!port) {
107 return isDefaultPortForProtocol(m_port, protocol); 139 if (isDefaultPortForProtocol(m_port, protocol))
140 return PortMatchingExact;
108 141
109 if (!m_port) 142 return PortNotMatching;
110 return isDefaultPortForProtocol(port, protocol); 143 }
111 144
112 return false; 145 if (!m_port) {
146 if (isDefaultPortForProtocol(port, protocol))
147 return PortMatchingExact;
148
149 return PortNotMatching;
150 }
151
152 return PortNotMatching;
113 } 153 }
114 154
115 bool CSPSource::subsumes(CSPSource* other) const { 155 bool CSPSource::subsumes(CSPSource* other) const {
116 if (!schemeMatches(other->m_scheme)) 156 if (!schemeMatches(other->m_scheme))
117 return false; 157 return false;
118 158
119 if (other->isSchemeOnly() || isSchemeOnly()) 159 if (other->isSchemeOnly() || isSchemeOnly())
120 return isSchemeOnly(); 160 return isSchemeOnly();
121 161
122 if ((m_hostWildcard == NoWildcard && other->m_hostWildcard == HasWildcard) || 162 if ((m_hostWildcard == NoWildcard && other->m_hostWildcard == HasWildcard) ||
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 static_cast<WebWildcardDisposition>(m_portWildcard); 257 static_cast<WebWildcardDisposition>(m_portWildcard);
218 sourceExpression.path = m_path; 258 sourceExpression.path = m_path;
219 return sourceExpression; 259 return sourceExpression;
220 } 260 }
221 261
222 DEFINE_TRACE(CSPSource) { 262 DEFINE_TRACE(CSPSource) {
223 visitor->trace(m_policy); 263 visitor->trace(m_policy);
224 } 264 }
225 265
226 } // namespace blink 266 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698