Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 | 28 |
| 29 #include "config.h" | 29 #include "config.h" |
| 30 #include "platform/weborigin/SecurityOrigin.h" | 30 #include "platform/weborigin/SecurityOrigin.h" |
| 31 | 31 |
| 32 #include "platform/RuntimeEnabledFeatures.h" | 32 #include "platform/RuntimeEnabledFeatures.h" |
| 33 #include "platform/weborigin/KURL.h" | 33 #include "platform/weborigin/KURL.h" |
| 34 #include "platform/weborigin/KnownPorts.h" | 34 #include "platform/weborigin/KnownPorts.h" |
| 35 #include "platform/weborigin/SchemeRegistry.h" | 35 #include "platform/weborigin/SchemeRegistry.h" |
| 36 #include "platform/weborigin/SecurityOriginCache.h" | 36 #include "platform/weborigin/SecurityOriginCache.h" |
| 37 #include "platform/weborigin/SecurityPolicy.h" | 37 #include "platform/weborigin/SecurityPolicy.h" |
| 38 #include "public/platform/Platform.h" | |
| 38 #include "url/url_canon_ip.h" | 39 #include "url/url_canon_ip.h" |
| 39 #include "wtf/HexNumber.h" | 40 #include "wtf/HexNumber.h" |
| 40 #include "wtf/MainThread.h" | 41 #include "wtf/MainThread.h" |
| 41 #include "wtf/NotFound.h" | 42 #include "wtf/NotFound.h" |
| 42 #include "wtf/OwnPtr.h" | 43 #include "wtf/OwnPtr.h" |
| 43 #include "wtf/PassOwnPtr.h" | 44 #include "wtf/PassOwnPtr.h" |
| 44 #include "wtf/StdLibExtras.h" | 45 #include "wtf/StdLibExtras.h" |
| 45 #include "wtf/text/StringBuilder.h" | 46 #include "wtf/text/StringBuilder.h" |
| 46 | 47 |
| 47 namespace blink { | 48 namespace blink { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 return false; | 119 return false; |
| 119 } | 120 } |
| 120 | 121 |
| 121 SecurityOrigin::SecurityOrigin(const KURL& url) | 122 SecurityOrigin::SecurityOrigin(const KURL& url) |
| 122 : m_protocol(url.protocol().isNull() ? "" : url.protocol().lower()) | 123 : m_protocol(url.protocol().isNull() ? "" : url.protocol().lower()) |
| 123 , m_host(url.host().isNull() ? "" : url.host().lower()) | 124 , m_host(url.host().isNull() ? "" : url.host().lower()) |
| 124 , m_port(url.port()) | 125 , m_port(url.port()) |
| 125 , m_effectivePort(url.port() ? url.port() : defaultPortForProtocol(m_protoco l)) | 126 , m_effectivePort(url.port() ? url.port() : defaultPortForProtocol(m_protoco l)) |
| 126 , m_isUnique(false) | 127 , m_isUnique(false) |
| 127 , m_universalAccess(false) | 128 , m_universalAccess(false) |
| 129 , m_universalAccessForFileOrigins(false) | |
| 128 , m_domainWasSetInDOM(false) | 130 , m_domainWasSetInDOM(false) |
| 129 , m_blockLocalAccessFromLocalOrigin(false) | 131 , m_blockLocalAccessFromLocalOrigin(false) |
| 130 { | 132 { |
| 131 // Suborigins are serialized into the host, so extract it if necessary. | 133 // Suborigins are serialized into the host, so extract it if necessary. |
| 132 String suboriginName; | 134 String suboriginName; |
| 133 if (deserializeSuboriginAndHost(m_host, suboriginName, m_host)) | 135 if (deserializeSuboriginAndHost(m_host, suboriginName, m_host)) |
| 134 addSuborigin(suboriginName); | 136 addSuborigin(suboriginName); |
| 135 | 137 |
| 136 // document.domain starts as m_host, but can be set by the DOM. | 138 // document.domain starts as m_host, but can be set by the DOM. |
| 137 m_domain = m_host; | 139 m_domain = m_host; |
| 138 | 140 |
| 139 if (isDefaultPortForProtocol(m_port, m_protocol)) | 141 if (isDefaultPortForProtocol(m_port, m_protocol)) |
| 140 m_port = InvalidPort; | 142 m_port = InvalidPort; |
| 141 | 143 |
| 142 // By default, only local SecurityOrigins can load local resources. | 144 // By default, only local SecurityOrigins can load local resources. |
| 143 m_canLoadLocalResources = isLocal(); | 145 m_canLoadLocalResources = isLocal(); |
| 144 } | 146 } |
| 145 | 147 |
| 146 SecurityOrigin::SecurityOrigin() | 148 SecurityOrigin::SecurityOrigin() |
| 147 : m_protocol("") | 149 : m_protocol("") |
| 148 , m_host("") | 150 , m_host("") |
| 149 , m_domain("") | 151 , m_domain("") |
| 150 , m_suboriginName(WTF::String()) | 152 , m_suboriginName(WTF::String()) |
| 151 , m_port(InvalidPort) | 153 , m_port(InvalidPort) |
| 152 , m_effectivePort(InvalidPort) | 154 , m_effectivePort(InvalidPort) |
| 153 , m_isUnique(true) | 155 , m_isUnique(true) |
| 154 , m_universalAccess(false) | 156 , m_universalAccess(false) |
| 157 , m_universalAccessForFileOrigins(false) | |
| 155 , m_domainWasSetInDOM(false) | 158 , m_domainWasSetInDOM(false) |
| 156 , m_canLoadLocalResources(false) | 159 , m_canLoadLocalResources(false) |
| 157 , m_blockLocalAccessFromLocalOrigin(false) | 160 , m_blockLocalAccessFromLocalOrigin(false) |
| 158 { | 161 { |
| 159 } | 162 } |
| 160 | 163 |
| 161 SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) | 164 SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) |
| 162 : m_protocol(other->m_protocol.isolatedCopy()) | 165 : m_protocol(other->m_protocol.isolatedCopy()) |
| 163 , m_host(other->m_host.isolatedCopy()) | 166 , m_host(other->m_host.isolatedCopy()) |
| 164 , m_domain(other->m_domain.isolatedCopy()) | 167 , m_domain(other->m_domain.isolatedCopy()) |
| 165 , m_suboriginName(other->m_suboriginName) | 168 , m_suboriginName(other->m_suboriginName) |
| 166 , m_port(other->m_port) | 169 , m_port(other->m_port) |
| 167 , m_effectivePort(other->m_effectivePort) | 170 , m_effectivePort(other->m_effectivePort) |
| 168 , m_isUnique(other->m_isUnique) | 171 , m_isUnique(other->m_isUnique) |
| 169 , m_universalAccess(other->m_universalAccess) | 172 , m_universalAccess(other->m_universalAccess) |
| 173 , m_universalAccessForFileOrigins(other->m_universalAccessForFileOrigins) | |
| 170 , m_domainWasSetInDOM(other->m_domainWasSetInDOM) | 174 , m_domainWasSetInDOM(other->m_domainWasSetInDOM) |
| 171 , m_canLoadLocalResources(other->m_canLoadLocalResources) | 175 , m_canLoadLocalResources(other->m_canLoadLocalResources) |
| 172 , m_blockLocalAccessFromLocalOrigin(other->m_blockLocalAccessFromLocalOrigin ) | 176 , m_blockLocalAccessFromLocalOrigin(other->m_blockLocalAccessFromLocalOrigin ) |
| 173 { | 177 { |
| 174 } | 178 } |
| 175 | 179 |
| 176 PassRefPtr<SecurityOrigin> SecurityOrigin::create(const KURL& url) | 180 PassRefPtr<SecurityOrigin> SecurityOrigin::create(const KURL& url) |
| 177 { | 181 { |
| 178 if (RefPtr<SecurityOrigin> origin = cachedOrigin(url)) | 182 if (RefPtr<SecurityOrigin> origin = cachedOrigin(url)) |
| 179 return origin.release(); | 183 return origin.release(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 return true; | 231 return true; |
| 228 | 232 |
| 229 if (SecurityPolicy::isOriginWhiteListedTrustworthy(*SecurityOrigin::create(u rl).get())) | 233 if (SecurityPolicy::isOriginWhiteListedTrustworthy(*SecurityOrigin::create(u rl).get())) |
| 230 return true; | 234 return true; |
| 231 | 235 |
| 232 return false; | 236 return false; |
| 233 } | 237 } |
| 234 | 238 |
| 235 bool SecurityOrigin::canAccess(const SecurityOrigin* other) const | 239 bool SecurityOrigin::canAccess(const SecurityOrigin* other) const |
| 236 { | 240 { |
| 237 if (m_universalAccess) | 241 if (m_universalAccess) { |
| 242 // TODO(mkwst): I would love to make this a RELEASE_ASSERT_WITH_SECURITY _IMPLICATIONS, but that | |
| 243 // would be seriously expensive as it would inject an IPC to the embedde r on this very hot path. | |
| 244 ASSERT(blink::Platform::current()->canGrantUniversalAccess()); | |
|
esprehn
2015/12/10 08:06:44
you don't need the blink:: prefix, also this shoul
| |
| 245 return true; | |
| 246 } | |
| 247 | |
| 248 if (m_universalAccessForFileOrigins && isLocal()) | |
| 238 return true; | 249 return true; |
| 239 | 250 |
| 240 if (this == other) | 251 if (this == other) |
| 241 return true; | 252 return true; |
| 242 | 253 |
| 243 if (isUnique() || other->isUnique()) | 254 if (isUnique() || other->isUnique()) |
| 244 return false; | 255 return false; |
| 245 | 256 |
| 246 // document.domain handling, as per https://html.spec.whatwg.org/multipage/b rowsers.html#dom-document-domain: | 257 // document.domain handling, as per https://html.spec.whatwg.org/multipage/b rowsers.html#dom-document-domain: |
| 247 // | 258 // |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 | 292 |
| 282 bool SecurityOrigin::passesFileCheck(const SecurityOrigin* other) const | 293 bool SecurityOrigin::passesFileCheck(const SecurityOrigin* other) const |
| 283 { | 294 { |
| 284 ASSERT(isLocal() && other->isLocal()); | 295 ASSERT(isLocal() && other->isLocal()); |
| 285 | 296 |
| 286 return !m_blockLocalAccessFromLocalOrigin && !other->m_blockLocalAccessFromL ocalOrigin; | 297 return !m_blockLocalAccessFromLocalOrigin && !other->m_blockLocalAccessFromL ocalOrigin; |
| 287 } | 298 } |
| 288 | 299 |
| 289 bool SecurityOrigin::canRequest(const KURL& url) const | 300 bool SecurityOrigin::canRequest(const KURL& url) const |
| 290 { | 301 { |
| 291 if (m_universalAccess) | 302 if (m_universalAccess) { |
| 303 // TODO(mkwst): I would love to make this a RELEASE_ASSERT_WITH_SECURITY _IMPLICATIONS, but that | |
| 304 // would be seriously expensive as it would inject an IPC to the embedde r on this very hot path. | |
| 305 ASSERT(blink::Platform::current()->canGrantUniversalAccess()); | |
|
esprehn
2015/12/10 08:06:44
ditto
| |
| 306 return true; | |
| 307 } | |
| 308 | |
| 309 if (m_universalAccessForFileOrigins && isLocal()) | |
| 292 return true; | 310 return true; |
| 293 | 311 |
| 294 if (cachedOrigin(url) == this) | 312 if (cachedOrigin(url) == this) |
| 295 return true; | 313 return true; |
| 296 | 314 |
| 297 if (isUnique()) | 315 if (isUnique()) |
| 298 return false; | 316 return false; |
| 299 | 317 |
| 300 RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url); | 318 RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url); |
| 301 | 319 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 330 // data URL security, then we can remove this function in favor of | 348 // data URL security, then we can remove this function in favor of |
| 331 // !canRequest. | 349 // !canRequest. |
| 332 if (url.protocolIsData()) | 350 if (url.protocolIsData()) |
| 333 return false; | 351 return false; |
| 334 | 352 |
| 335 return true; | 353 return true; |
| 336 } | 354 } |
| 337 | 355 |
| 338 bool SecurityOrigin::canDisplay(const KURL& url) const | 356 bool SecurityOrigin::canDisplay(const KURL& url) const |
| 339 { | 357 { |
| 340 if (m_universalAccess) | 358 if (m_universalAccess) { |
| 359 // TODO(mkwst): I would love to make this a RELEASE_ASSERT_WITH_SECURITY _IMPLICATIONS, but that | |
| 360 // would be seriously expensive as it would inject an IPC to the embedde r on this very hot path. | |
| 361 ASSERT(blink::Platform::current()->canGrantUniversalAccess()); | |
|
esprehn
2015/12/10 08:06:44
ditto
| |
| 362 return true; | |
| 363 } | |
| 364 | |
| 365 if (m_universalAccessForFileOrigins && isLocal()) | |
| 341 return true; | 366 return true; |
| 342 | 367 |
| 343 String protocol = url.protocol().lower(); | 368 String protocol = url.protocol().lower(); |
| 344 | 369 |
| 345 if (SchemeRegistry::canDisplayOnlyIfCanRequest(protocol)) | 370 if (SchemeRegistry::canDisplayOnlyIfCanRequest(protocol)) |
| 346 return canRequest(url); | 371 return canRequest(url); |
| 347 | 372 |
| 348 if (SchemeRegistry::shouldTreatURLSchemeAsDisplayIsolated(protocol)) | 373 if (SchemeRegistry::shouldTreatURLSchemeAsDisplayIsolated(protocol)) |
| 349 return m_protocol == protocol || SecurityPolicy::isAccessToURLWhiteListe d(this, url); | 374 return m_protocol == protocol || SecurityPolicy::isAccessToURLWhiteListe d(this, url); |
| 350 | 375 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 371 { | 396 { |
| 372 // Granting privileges to some, but not all, documents in a SecurityOrigin | 397 // Granting privileges to some, but not all, documents in a SecurityOrigin |
| 373 // is a security hazard because the documents without the privilege can | 398 // is a security hazard because the documents without the privilege can |
| 374 // obtain the privilege by injecting script into the documents that have | 399 // obtain the privilege by injecting script into the documents that have |
| 375 // been granted the privilege. | 400 // been granted the privilege. |
| 376 m_canLoadLocalResources = true; | 401 m_canLoadLocalResources = true; |
| 377 } | 402 } |
| 378 | 403 |
| 379 void SecurityOrigin::grantUniversalAccess() | 404 void SecurityOrigin::grantUniversalAccess() |
| 380 { | 405 { |
| 406 // This must not be granted unless the embedder says we can grant this kind of permission. | |
| 407 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(blink::Platform::current()->canGran tUniversalAccess()); | |
| 381 m_universalAccess = true; | 408 m_universalAccess = true; |
| 382 } | 409 } |
| 383 | 410 |
| 411 void SecurityOrigin::grantUniversalAccessForFileOrigins() | |
| 412 { | |
| 413 // This must not be granted to non-local origins, hence the release assert. | |
| 414 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(isLocal()); | |
| 415 m_universalAccessForFileOrigins = true; | |
| 416 } | |
| 417 | |
| 384 void SecurityOrigin::blockLocalAccessFromLocalOrigin() | 418 void SecurityOrigin::blockLocalAccessFromLocalOrigin() |
| 385 { | 419 { |
| 386 ASSERT(isLocal()); | 420 ASSERT(isLocal()); |
| 387 m_blockLocalAccessFromLocalOrigin = true; | 421 m_blockLocalAccessFromLocalOrigin = true; |
| 388 } | 422 } |
| 389 | 423 |
| 390 bool SecurityOrigin::isLocal() const | 424 bool SecurityOrigin::isLocal() const |
| 391 { | 425 { |
| 392 return SchemeRegistry::shouldTreatURLSchemeAsLocal(m_protocol); | 426 return SchemeRegistry::shouldTreatURLSchemeAsLocal(m_protocol); |
| 393 } | 427 } |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 528 { | 562 { |
| 529 ASSERT(isMainThread()); | 563 ASSERT(isMainThread()); |
| 530 DEFINE_STATIC_LOCAL(const KURL, uniqueSecurityOriginURL, (ParsedURLString, " data:,")); | 564 DEFINE_STATIC_LOCAL(const KURL, uniqueSecurityOriginURL, (ParsedURLString, " data:,")); |
| 531 return uniqueSecurityOriginURL; | 565 return uniqueSecurityOriginURL; |
| 532 } | 566 } |
| 533 | 567 |
| 534 PassOwnPtr<SecurityOrigin::PrivilegeData> SecurityOrigin::createPrivilegeData() const | 568 PassOwnPtr<SecurityOrigin::PrivilegeData> SecurityOrigin::createPrivilegeData() const |
| 535 { | 569 { |
| 536 OwnPtr<PrivilegeData> privilegeData = adoptPtr(new PrivilegeData); | 570 OwnPtr<PrivilegeData> privilegeData = adoptPtr(new PrivilegeData); |
| 537 privilegeData->m_universalAccess = m_universalAccess; | 571 privilegeData->m_universalAccess = m_universalAccess; |
| 572 privilegeData->m_universalAccessForFileOrigins = m_universalAccessForFileOri gins; | |
| 538 privilegeData->m_canLoadLocalResources = m_canLoadLocalResources; | 573 privilegeData->m_canLoadLocalResources = m_canLoadLocalResources; |
| 539 privilegeData->m_blockLocalAccessFromLocalOrigin = m_blockLocalAccessFromLoc alOrigin; | 574 privilegeData->m_blockLocalAccessFromLocalOrigin = m_blockLocalAccessFromLoc alOrigin; |
| 540 return privilegeData.release(); | 575 return privilegeData.release(); |
| 541 } | 576 } |
| 542 | 577 |
| 543 void SecurityOrigin::transferPrivilegesFrom(PassOwnPtr<PrivilegeData> privilegeD ata) | 578 void SecurityOrigin::transferPrivilegesFrom(PassOwnPtr<PrivilegeData> privilegeD ata) |
| 544 { | 579 { |
| 545 m_universalAccess = privilegeData->m_universalAccess; | 580 m_universalAccess = privilegeData->m_universalAccess; |
| 581 m_universalAccessForFileOrigins = privilegeData->m_universalAccessForFileOri gins; | |
| 546 m_canLoadLocalResources = privilegeData->m_canLoadLocalResources; | 582 m_canLoadLocalResources = privilegeData->m_canLoadLocalResources; |
| 547 m_blockLocalAccessFromLocalOrigin = privilegeData->m_blockLocalAccessFromLoc alOrigin; | 583 m_blockLocalAccessFromLocalOrigin = privilegeData->m_blockLocalAccessFromLoc alOrigin; |
| 548 } | 584 } |
| 549 | 585 |
| 550 } // namespace blink | 586 } // namespace blink |
| OLD | NEW |