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 11 matching lines...) Expand all Loading... | |
| 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 */ | 27 */ |
| 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/weborigin/KURL.h" | 33 #include "platform/weborigin/KURL.h" |
| 33 #include "platform/weborigin/KnownPorts.h" | 34 #include "platform/weborigin/KnownPorts.h" |
| 34 #include "platform/weborigin/SchemeRegistry.h" | 35 #include "platform/weborigin/SchemeRegistry.h" |
| 35 #include "platform/weborigin/SecurityOriginCache.h" | 36 #include "platform/weborigin/SecurityOriginCache.h" |
| 36 #include "platform/weborigin/SecurityPolicy.h" | 37 #include "platform/weborigin/SecurityPolicy.h" |
| 37 #include "url/url_canon_ip.h" | 38 #include "url/url_canon_ip.h" |
| 38 #include "wtf/HexNumber.h" | 39 #include "wtf/HexNumber.h" |
| 39 #include "wtf/MainThread.h" | 40 #include "wtf/MainThread.h" |
| 41 #include "wtf/NotFound.h" | |
| 40 #include "wtf/StdLibExtras.h" | 42 #include "wtf/StdLibExtras.h" |
| 41 #include "wtf/text/StringBuilder.h" | 43 #include "wtf/text/StringBuilder.h" |
| 42 | 44 |
| 43 namespace blink { | 45 namespace blink { |
| 44 | 46 |
| 45 const int InvalidPort = 0; | 47 const int InvalidPort = 0; |
| 46 const int MaxAllowedPort = 65535; | 48 const int MaxAllowedPort = 65535; |
| 47 | 49 |
| 48 static SecurityOriginCache* s_originCache = 0; | 50 static SecurityOriginCache* s_originCache = 0; |
| 49 | 51 |
| 50 static bool schemeRequiresAuthority(const KURL& url) | 52 static bool schemeRequiresAuthority(const KURL& url) |
| 51 { | 53 { |
| 52 // We expect URLs with these schemes to have authority components. If the | 54 // We expect URLs with these schemes to have authority components. If the |
| 53 // URL lacks an authority component, we get concerned and mark the origin | 55 // URL lacks an authority component, we get concerned and mark the origin |
| 54 // as unique. | 56 // as unique. |
| 55 return url.protocolIsInHTTPFamily() || url.protocolIs("ftp"); | 57 return url.protocolIsInHTTPFamily() || url.protocolIs("ftp"); |
| 56 } | 58 } |
| 57 | 59 |
| 58 static SecurityOrigin* cachedOrigin(const KURL& url) | 60 static SecurityOrigin* cachedOrigin(const KURL& url) |
| 59 { | 61 { |
| 60 if (s_originCache) | 62 if (s_originCache) |
| 61 return s_originCache->cachedOrigin(url); | 63 return s_originCache->cachedOrigin(url); |
| 62 return 0; | 64 return 0; |
| 63 } | 65 } |
| 64 | 66 |
| 67 static bool sameSuborigin(const SecurityOrigin* origin1, const SecurityOrigin* o rigin2) | |
| 68 { | |
| 69 // If either origin has a suborigin set, both must have the same suborigin. | |
| 70 return origin1->suboriginName() == origin2->suboriginName(); | |
| 71 } | |
| 72 | |
| 65 bool SecurityOrigin::shouldUseInnerURL(const KURL& url) | 73 bool SecurityOrigin::shouldUseInnerURL(const KURL& url) |
| 66 { | 74 { |
| 67 // FIXME: Blob URLs don't have inner URLs. Their form is "blob:<inner-origin >/<UUID>", so treating the part after "blob:" as a URL is incorrect. | 75 // FIXME: Blob URLs don't have inner URLs. Their form is "blob:<inner-origin >/<UUID>", so treating the part after "blob:" as a URL is incorrect. |
| 68 if (url.protocolIs("blob")) | 76 if (url.protocolIs("blob")) |
| 69 return true; | 77 return true; |
| 70 if (url.protocolIs("filesystem")) | 78 if (url.protocolIs("filesystem")) |
| 71 return true; | 79 return true; |
| 72 return false; | 80 return false; |
| 73 } | 81 } |
| 74 | 82 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 SecurityOrigin::SecurityOrigin(const KURL& url) | 127 SecurityOrigin::SecurityOrigin(const KURL& url) |
| 120 : m_protocol(url.protocol().isNull() ? "" : url.protocol().lower()) | 128 : m_protocol(url.protocol().isNull() ? "" : url.protocol().lower()) |
| 121 , m_host(url.host().isNull() ? "" : url.host().lower()) | 129 , m_host(url.host().isNull() ? "" : url.host().lower()) |
| 122 , m_port(url.port()) | 130 , m_port(url.port()) |
| 123 , m_isUnique(false) | 131 , m_isUnique(false) |
| 124 , m_universalAccess(false) | 132 , m_universalAccess(false) |
| 125 , m_domainWasSetInDOM(false) | 133 , m_domainWasSetInDOM(false) |
| 126 , m_enforceFilePathSeparation(false) | 134 , m_enforceFilePathSeparation(false) |
| 127 , m_needsDatabaseIdentifierQuirkForFiles(false) | 135 , m_needsDatabaseIdentifierQuirkForFiles(false) |
| 128 { | 136 { |
| 137 // Suborigins are serialized into the host, so extract it if necessary. | |
| 138 String suboriginName; | |
| 139 if (deserializeSuboriginAndHost(m_host, suboriginName, m_host)) | |
| 140 addSuborigin(suboriginName); | |
| 141 | |
| 129 // document.domain starts as m_host, but can be set by the DOM. | 142 // document.domain starts as m_host, but can be set by the DOM. |
| 130 m_domain = m_host; | 143 m_domain = m_host; |
| 131 | 144 |
| 132 if (isDefaultPortForProtocol(m_port, m_protocol)) | 145 if (isDefaultPortForProtocol(m_port, m_protocol)) |
| 133 m_port = InvalidPort; | 146 m_port = InvalidPort; |
| 134 | 147 |
| 135 // By default, only local SecurityOrigins can load local resources. | 148 // By default, only local SecurityOrigins can load local resources. |
| 136 m_canLoadLocalResources = isLocal(); | 149 m_canLoadLocalResources = isLocal(); |
| 137 | 150 |
| 138 if (m_canLoadLocalResources) | 151 if (m_canLoadLocalResources) |
| 139 m_filePath = url.path(); // In case enforceFilePathSeparation() is calle d. | 152 m_filePath = url.path(); // In case enforceFilePathSeparation() is calle d. |
| 140 } | 153 } |
| 141 | 154 |
| 142 SecurityOrigin::SecurityOrigin() | 155 SecurityOrigin::SecurityOrigin() |
| 143 : m_protocol("") | 156 : m_protocol("") |
| 144 , m_host("") | 157 , m_host("") |
| 145 , m_domain("") | 158 , m_domain("") |
| 159 , m_suboriginName(WTF::String()) | |
| 146 , m_port(InvalidPort) | 160 , m_port(InvalidPort) |
| 147 , m_isUnique(true) | 161 , m_isUnique(true) |
| 148 , m_universalAccess(false) | 162 , m_universalAccess(false) |
| 149 , m_domainWasSetInDOM(false) | 163 , m_domainWasSetInDOM(false) |
| 150 , m_canLoadLocalResources(false) | 164 , m_canLoadLocalResources(false) |
| 151 , m_enforceFilePathSeparation(false) | 165 , m_enforceFilePathSeparation(false) |
| 152 , m_needsDatabaseIdentifierQuirkForFiles(false) | 166 , m_needsDatabaseIdentifierQuirkForFiles(false) |
| 153 { | 167 { |
| 154 } | 168 } |
| 155 | 169 |
| 156 SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) | 170 SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) |
| 157 : m_protocol(other->m_protocol.isolatedCopy()) | 171 : m_protocol(other->m_protocol.isolatedCopy()) |
| 158 , m_host(other->m_host.isolatedCopy()) | 172 , m_host(other->m_host.isolatedCopy()) |
| 159 , m_domain(other->m_domain.isolatedCopy()) | 173 , m_domain(other->m_domain.isolatedCopy()) |
| 160 , m_filePath(other->m_filePath.isolatedCopy()) | 174 , m_filePath(other->m_filePath.isolatedCopy()) |
| 175 , m_suboriginName(other->m_suboriginName) | |
| 161 , m_port(other->m_port) | 176 , m_port(other->m_port) |
| 162 , m_isUnique(other->m_isUnique) | 177 , m_isUnique(other->m_isUnique) |
| 163 , m_universalAccess(other->m_universalAccess) | 178 , m_universalAccess(other->m_universalAccess) |
| 164 , m_domainWasSetInDOM(other->m_domainWasSetInDOM) | 179 , m_domainWasSetInDOM(other->m_domainWasSetInDOM) |
| 165 , m_canLoadLocalResources(other->m_canLoadLocalResources) | 180 , m_canLoadLocalResources(other->m_canLoadLocalResources) |
| 166 , m_enforceFilePathSeparation(other->m_enforceFilePathSeparation) | 181 , m_enforceFilePathSeparation(other->m_enforceFilePathSeparation) |
| 167 , m_needsDatabaseIdentifierQuirkForFiles(other->m_needsDatabaseIdentifierQui rkForFiles) | 182 , m_needsDatabaseIdentifierQuirkForFiles(other->m_needsDatabaseIdentifierQui rkForFiles) |
| 168 { | 183 { |
| 169 } | 184 } |
| 170 | 185 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 193 return adoptRef(new SecurityOrigin(url)); | 208 return adoptRef(new SecurityOrigin(url)); |
| 194 } | 209 } |
| 195 | 210 |
| 196 PassRefPtr<SecurityOrigin> SecurityOrigin::createUnique() | 211 PassRefPtr<SecurityOrigin> SecurityOrigin::createUnique() |
| 197 { | 212 { |
| 198 RefPtr<SecurityOrigin> origin = adoptRef(new SecurityOrigin()); | 213 RefPtr<SecurityOrigin> origin = adoptRef(new SecurityOrigin()); |
| 199 ASSERT(origin->isUnique()); | 214 ASSERT(origin->isUnique()); |
| 200 return origin.release(); | 215 return origin.release(); |
| 201 } | 216 } |
| 202 | 217 |
| 218 void SecurityOrigin::addSuborigin(const String& suborigin) | |
| 219 { | |
| 220 ASSERT(RuntimeEnabledFeatures::suboriginsEnabled()); | |
| 221 // Changing suborigins midstream is bad. Very bad. It should not happen. | |
| 222 // This is, in fact, one of the very basic invariants that makes suborigins | |
| 223 // an effective security tool. | |
| 224 RELEASE_ASSERT(m_suboriginName.isNull() || m_suboriginName == suborigin); | |
| 225 m_suboriginName = suborigin; | |
| 226 } | |
| 227 | |
| 203 PassRefPtr<SecurityOrigin> SecurityOrigin::isolatedCopy() const | 228 PassRefPtr<SecurityOrigin> SecurityOrigin::isolatedCopy() const |
| 204 { | 229 { |
| 205 return adoptRef(new SecurityOrigin(this)); | 230 return adoptRef(new SecurityOrigin(this)); |
| 206 } | 231 } |
| 207 | 232 |
| 208 void SecurityOrigin::setDomainFromDOM(const String& newDomain) | 233 void SecurityOrigin::setDomainFromDOM(const String& newDomain) |
| 209 { | 234 { |
| 210 m_domainWasSetInDOM = true; | 235 m_domainWasSetInDOM = true; |
| 211 m_domain = newDomain.lower(); | 236 m_domain = newDomain.lower(); |
| 212 } | 237 } |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 466 String SecurityOrigin::toRawString() const | 491 String SecurityOrigin::toRawString() const |
| 467 { | 492 { |
| 468 if (m_protocol == "file") | 493 if (m_protocol == "file") |
| 469 return "file://"; | 494 return "file://"; |
| 470 | 495 |
| 471 StringBuilder result; | 496 StringBuilder result; |
| 472 buildRawString(result); | 497 buildRawString(result); |
| 473 return result.toString(); | 498 return result.toString(); |
| 474 } | 499 } |
| 475 | 500 |
| 501 // Returns true if and only if a suborigin component was found. If false, no | |
| 502 // guarantees about the return value |suboriginName| are made. | |
| 503 bool SecurityOrigin::deserializeSuboriginAndHost(const String& oldHost, String& suboriginName, String& newHost) | |
| 504 { | |
| 505 if (!RuntimeEnabledFeatures::suboriginsEnabled()) | |
| 506 return false; | |
| 507 | |
| 508 size_t suboriginEnd = oldHost.find('_'); | |
|
jochen (gone - plz use gerrit)
2015/04/27 19:35:10
underscore looks odd but is ok i guess
jww
2015/05/30 01:11:07
Yeah, I'm happy to discuss what we should use as a
| |
| 509 // Suborigins cannot be empty | |
| 510 if (suboriginEnd == 0 || suboriginEnd == WTF::kNotFound) | |
| 511 return false; | |
| 512 | |
| 513 suboriginName = oldHost.substring(0, suboriginEnd); | |
| 514 newHost = oldHost.substring(suboriginEnd + 1); | |
| 515 | |
| 516 return true; | |
| 517 } | |
| 518 | |
| 519 | |
| 476 AtomicString SecurityOrigin::toRawAtomicString() const | 520 AtomicString SecurityOrigin::toRawAtomicString() const |
| 477 { | 521 { |
| 478 if (m_protocol == "file") | 522 if (m_protocol == "file") |
| 479 return AtomicString("file://", AtomicString::ConstructFromLiteral); | 523 return AtomicString("file://", AtomicString::ConstructFromLiteral); |
| 480 | 524 |
| 481 StringBuilder result; | 525 StringBuilder result; |
| 482 buildRawString(result); | 526 buildRawString(result); |
| 483 return result.toAtomicString(); | 527 return result.toAtomicString(); |
| 484 } | 528 } |
| 485 | 529 |
| 486 inline void SecurityOrigin::buildRawString(StringBuilder& builder) const | 530 void SecurityOrigin::buildRawString(StringBuilder& builder) const |
| 487 { | 531 { |
| 488 builder.reserveCapacity(m_protocol.length() + m_host.length() + 10); | |
| 489 builder.append(m_protocol); | 532 builder.append(m_protocol); |
| 490 builder.appendLiteral("://"); | 533 builder.appendLiteral("://"); |
| 534 if (hasSuborigin()) { | |
| 535 builder.append(m_suboriginName); | |
| 536 builder.appendLiteral("_"); | |
| 537 } | |
| 491 builder.append(m_host); | 538 builder.append(m_host); |
| 492 | 539 |
| 493 if (m_port) { | 540 if (m_port) { |
| 494 builder.append(':'); | 541 builder.append(':'); |
| 495 builder.appendNumber(m_port); | 542 builder.appendNumber(m_port); |
| 496 } | 543 } |
| 497 } | 544 } |
| 498 | 545 |
| 499 PassRefPtr<SecurityOrigin> SecurityOrigin::createFromString(const String& origin String) | 546 PassRefPtr<SecurityOrigin> SecurityOrigin::createFromString(const String& origin String) |
| 500 { | 547 { |
| 501 return SecurityOrigin::create(KURL(KURL(), originString)); | 548 return SecurityOrigin::create(KURL(KURL(), originString)); |
| 502 } | 549 } |
| 503 | 550 |
| 504 PassRefPtr<SecurityOrigin> SecurityOrigin::create(const String& protocol, const String& host, int port) | 551 PassRefPtr<SecurityOrigin> SecurityOrigin::create(const String& protocol, const String& host, int port) |
| 505 { | 552 { |
| 506 if (port < 0 || port > MaxAllowedPort) | 553 if (port < 0 || port > MaxAllowedPort) |
| 507 return createUnique(); | 554 return createUnique(); |
| 508 String decodedHost = decodeURLEscapeSequences(host); | 555 String decodedHost = decodeURLEscapeSequences(host); |
| 509 return create(KURL(KURL(), protocol + "://" + host + ":" + String::number(po rt) + "/")); | 556 return create(KURL(KURL(), protocol + "://" + host + ":" + String::number(po rt) + "/")); |
| 510 } | 557 } |
| 511 | 558 |
| 512 bool SecurityOrigin::isSameSchemeHostPort(const SecurityOrigin* other) const | 559 bool SecurityOrigin::isSameSchemeHostPort(const SecurityOrigin* other) const |
| 513 { | 560 { |
| 561 if (!sameSuborigin(this, other)) | |
| 562 return false; | |
| 563 | |
| 514 if (m_host != other->m_host) | 564 if (m_host != other->m_host) |
| 515 return false; | 565 return false; |
| 516 | 566 |
| 517 if (m_protocol != other->m_protocol) | 567 if (m_protocol != other->m_protocol) |
| 518 return false; | 568 return false; |
| 519 | 569 |
| 520 if (m_port != other->m_port) | 570 if (m_port != other->m_port) |
| 521 return false; | 571 return false; |
| 522 | 572 |
| 523 if (isLocal() && !passesFileCheck(other)) | 573 if (isLocal() && !passesFileCheck(other)) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 534 } | 584 } |
| 535 | 585 |
| 536 void SecurityOrigin::transferPrivilegesFrom(const SecurityOrigin& origin) | 586 void SecurityOrigin::transferPrivilegesFrom(const SecurityOrigin& origin) |
| 537 { | 587 { |
| 538 m_universalAccess = origin.m_universalAccess; | 588 m_universalAccess = origin.m_universalAccess; |
| 539 m_canLoadLocalResources = origin.m_canLoadLocalResources; | 589 m_canLoadLocalResources = origin.m_canLoadLocalResources; |
| 540 m_enforceFilePathSeparation = origin.m_enforceFilePathSeparation; | 590 m_enforceFilePathSeparation = origin.m_enforceFilePathSeparation; |
| 541 } | 591 } |
| 542 | 592 |
| 543 } // namespace blink | 593 } // namespace blink |
| OLD | NEW |