Commit 33d6af40 authored by jochen's avatar jochen Committed by Commit bot

Merge SecurityOrigin::canAccessCheckSuborigins into canAccess

Suborigins are supposed to make script from different suborigin
namespaces inaccessible to each other. canAccess (in spec terms
same-origin domain) is supposed to do that, so just fold the two
together

BUG=336894
R=mkwst@chromium.org

Review-Url: https://codereview.chromium.org/2805683005
Cr-Commit-Position: refs/heads/master@{#462872}
parent 76266573
...@@ -28,9 +28,9 @@ domain](https://html.spec.whatwg.org/multipage/browsers.html#same-origin-domain) ...@@ -28,9 +28,9 @@ domain](https://html.spec.whatwg.org/multipage/browsers.html#same-origin-domain)
using `SecurityOrigin::isSameSchemeHostPort`. using `SecurityOrigin::isSameSchemeHostPort`.
The [Suborigins spec](https://w3c.github.io/webappsec-suborigins/) extends The [Suborigins spec](https://w3c.github.io/webappsec-suborigins/) extends
HTML's definition of origins. To check for same-origin and same-origin domain HTML's definition of origins. To check for same-origin corresponds to
use `SecurityOrigin::canAccessCheckSuborigins` and `SecurityOrigin::isSameSchemeHostPortAndSuborigin` while the check for same-origin
`SecurityOrigin::isSameSchemeHostPortAndSuborigin`. domain already takes the suborigin into account.
### [Window object](https://html.spec.whatwg.org/#window) ### [Window object](https://html.spec.whatwg.org/#window)
......
...@@ -60,7 +60,7 @@ bool canAccessFrameInternal(const LocalDOMWindow* accessingWindow, ...@@ -60,7 +60,7 @@ bool canAccessFrameInternal(const LocalDOMWindow* accessingWindow,
const SecurityOrigin* accessingOrigin = const SecurityOrigin* accessingOrigin =
accessingWindow->document()->getSecurityOrigin(); accessingWindow->document()->getSecurityOrigin();
if (!accessingOrigin->canAccessCheckSuborigins(targetFrameOrigin)) if (!accessingOrigin->canAccess(targetFrameOrigin))
return false; return false;
// Notify the loader's client if the initial document has been accessed. // Notify the loader's client if the initial document has been accessed.
...@@ -241,7 +241,7 @@ bool BindingSecurity::shouldAllowNamedAccessTo(const DOMWindow* accessingWindow, ...@@ -241,7 +241,7 @@ bool BindingSecurity::shouldAllowNamedAccessTo(const DOMWindow* accessingWindow,
SECURITY_CHECK(!(targetWindow && targetWindow->frame()) || SECURITY_CHECK(!(targetWindow && targetWindow->frame()) ||
targetWindow == targetWindow->frame()->domWindow()); targetWindow == targetWindow->frame()->domWindow());
if (!accessingOrigin->canAccessCheckSuborigins(targetOrigin)) if (!accessingOrigin->canAccess(targetOrigin))
return false; return false;
// Note that there is no need to call back // Note that there is no need to call back
......
...@@ -256,10 +256,10 @@ bool CSSStyleSheet::canAccessRules() const { ...@@ -256,10 +256,10 @@ bool CSSStyleSheet::canAccessRules() const {
return true; return true;
if (document->getSecurityOrigin()->canRequestNoSuborigin(baseURL)) if (document->getSecurityOrigin()->canRequestNoSuborigin(baseURL))
return true; return true;
if (m_allowRuleAccessFromOrigin && if (m_allowRuleAccessFromOrigin && document->getSecurityOrigin()->canAccess(
document->getSecurityOrigin()->canAccessCheckSuborigins( m_allowRuleAccessFromOrigin.get())) {
m_allowRuleAccessFromOrigin.get()))
return true; return true;
}
return false; return false;
} }
......
...@@ -137,9 +137,10 @@ bool DOMWindow::isInsecureScriptAccess(LocalDOMWindow& callingWindow, ...@@ -137,9 +137,10 @@ bool DOMWindow::isInsecureScriptAccess(LocalDOMWindow& callingWindow,
// FIXME: The name canAccess seems to be a roundabout way to ask "can // FIXME: The name canAccess seems to be a roundabout way to ask "can
// execute script". Can we name the SecurityOrigin function better to make // execute script". Can we name the SecurityOrigin function better to make
// this more clear? // this more clear?
if (callingWindow.document()->getSecurityOrigin()->canAccessCheckSuborigins( if (callingWindow.document()->getSecurityOrigin()->canAccess(
frame()->securityContext()->getSecurityOrigin())) frame()->securityContext()->getSecurityOrigin())) {
return false; return false;
}
} }
callingWindow.printErrorMessage( callingWindow.printErrorMessage(
...@@ -270,8 +271,7 @@ String DOMWindow::crossDomainAccessErrorMessage( ...@@ -270,8 +271,7 @@ String DOMWindow::crossDomainAccessErrorMessage(
// It's possible for a remote frame to be same origin with respect to a // It's possible for a remote frame to be same origin with respect to a
// local frame, but it must still be treated as a disallowed cross-domain // local frame, but it must still be treated as a disallowed cross-domain
// access. See https://crbug.com/601629. // access. See https://crbug.com/601629.
ASSERT(frame()->isRemoteFrame() || DCHECK(frame()->isRemoteFrame() || !activeOrigin->canAccess(targetOrigin));
!activeOrigin->canAccessCheckSuborigins(targetOrigin));
String message = "Blocked a frame with origin \"" + activeOrigin->toString() + String message = "Blocked a frame with origin \"" + activeOrigin->toString() +
"\" from accessing a frame with origin \"" + "\" from accessing a frame with origin \"" +
......
...@@ -57,7 +57,7 @@ ServiceWorkerContainer* NavigatorServiceWorker::serviceWorker( ...@@ -57,7 +57,7 @@ ServiceWorkerContainer* NavigatorServiceWorker::serviceWorker(
ExceptionState& exceptionState) { ExceptionState& exceptionState) {
ExecutionContext* executionContext = scriptState->getExecutionContext(); ExecutionContext* executionContext = scriptState->getExecutionContext();
DCHECK(!navigator.frame() || DCHECK(!navigator.frame() ||
executionContext->getSecurityOrigin()->canAccessCheckSuborigins( executionContext->getSecurityOrigin()->canAccess(
navigator.frame()->securityContext()->getSecurityOrigin())); navigator.frame()->securityContext()->getSecurityOrigin()));
return NavigatorServiceWorker::from(navigator).serviceWorker( return NavigatorServiceWorker::from(navigator).serviceWorker(
navigator.frame(), exceptionState); navigator.frame(), exceptionState);
...@@ -69,7 +69,7 @@ ServiceWorkerContainer* NavigatorServiceWorker::serviceWorker( ...@@ -69,7 +69,7 @@ ServiceWorkerContainer* NavigatorServiceWorker::serviceWorker(
String& errorMessage) { String& errorMessage) {
ExecutionContext* executionContext = scriptState->getExecutionContext(); ExecutionContext* executionContext = scriptState->getExecutionContext();
DCHECK(!navigator.frame() || DCHECK(!navigator.frame() ||
executionContext->getSecurityOrigin()->canAccessCheckSuborigins( executionContext->getSecurityOrigin()->canAccess(
navigator.frame()->securityContext()->getSecurityOrigin())); navigator.frame()->securityContext()->getSecurityOrigin()));
return NavigatorServiceWorker::from(navigator).serviceWorker( return NavigatorServiceWorker::from(navigator).serviceWorker(
navigator.frame(), errorMessage); navigator.frame(), errorMessage);
......
...@@ -231,6 +231,12 @@ bool SecurityOrigin::canAccess(const SecurityOrigin* other) const { ...@@ -231,6 +231,12 @@ bool SecurityOrigin::canAccess(const SecurityOrigin* other) const {
if (isUnique() || other->isUnique()) if (isUnique() || other->isUnique())
return false; return false;
if (hasSuborigin() != other->hasSuborigin())
return false;
if (hasSuborigin() && suborigin()->name() != other->suborigin()->name())
return false;
// document.domain handling, as per // document.domain handling, as per
// https://html.spec.whatwg.org/multipage/browsers.html#dom-document-domain: // https://html.spec.whatwg.org/multipage/browsers.html#dom-document-domain:
// //
...@@ -257,17 +263,6 @@ bool SecurityOrigin::canAccess(const SecurityOrigin* other) const { ...@@ -257,17 +263,6 @@ bool SecurityOrigin::canAccess(const SecurityOrigin* other) const {
return canAccess; return canAccess;
} }
bool SecurityOrigin::canAccessCheckSuborigins(
const SecurityOrigin* other) const {
if (hasSuborigin() != other->hasSuborigin())
return false;
if (hasSuborigin() && suborigin()->name() != other->suborigin()->name())
return false;
return canAccess(other);
}
bool SecurityOrigin::passesFileCheck(const SecurityOrigin* other) const { bool SecurityOrigin::passesFileCheck(const SecurityOrigin* other) const {
ASSERT(isLocal() && other->isLocal()); ASSERT(isLocal() && other->isLocal());
......
...@@ -102,19 +102,9 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> { ...@@ -102,19 +102,9 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
// SecurityOrigin. For example, call this function before allowing // SecurityOrigin. For example, call this function before allowing
// script from one security origin to read or write objects from // script from one security origin to read or write objects from
// another SecurityOrigin. // another SecurityOrigin.
bool canAccess(const SecurityOrigin*) const;
// Same as canAccess, except that it adds an additional check to make sure
// that the SecurityOrigins have the same suborigin name. If you're not
// familiar with Suborigins, you probably want canAccess() for now.
// Suborigins is a spec in progress, and where it should be enforced is
// still in flux. See https://crbug.com/336894 for more details.
// //
// TODO(jww): Once the Suborigin spec has become more settled, and we are // This takes suborigins into account.
// confident in the correctness of our implementation, canAccess should be bool canAccess(const SecurityOrigin*) const;
// made to check the suborigin and this should be turned into
// canAccessBypassSuborigin check, which should be the exceptional case.
bool canAccessCheckSuborigins(const SecurityOrigin*) const;
// Returns true if this SecurityOrigin can read content retrieved from // Returns true if this SecurityOrigin can read content retrieved from
// the given URL. For example, call this function before issuing // the given URL. For example, call this function before issuing
...@@ -122,11 +112,10 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> { ...@@ -122,11 +112,10 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
bool canRequest(const KURL&) const; bool canRequest(const KURL&) const;
// Same as canRequest, except that it adds an additional check to make sure // Same as canRequest, except that it adds an additional check to make sure
// that the SecurityOrigin does not have a suborigin name. Like with // that the SecurityOrigin does not have a suborigin name. If you're not
// canAccessCheckSuborigins() above, if you're not familiar with // familiar with Suborigins, you probably want canRequest() for now.
// Suborigins, you probably want canRequest() for now. Suborigins is a spec // Suborigins is a spec in progress, and where it should be enforced is still
// in progress, and where it should be enforced is still in flux. See // in flux. See https://crbug.com/336894 for more details.
// https://crbug.com/336894 for more details.
// //
// TODO(jww): Once the Suborigin spec has become more settled, and we are // TODO(jww): Once the Suborigin spec has become more settled, and we are
// confident in the correctness of our implementation, canRequest should be // confident in the correctness of our implementation, canRequest should be
......
...@@ -334,17 +334,16 @@ TEST_F(SecurityOriginTest, CanAccess) { ...@@ -334,17 +334,16 @@ TEST_F(SecurityOriginTest, CanAccess) {
struct TestCase { struct TestCase {
bool canAccess; bool canAccess;
bool canAccessCheckSuborigins;
const char* origin1; const char* origin1;
const char* origin2; const char* origin2;
}; };
TestCase tests[] = { TestCase tests[] = {
{true, true, "https://foobar.com", "https://foobar.com"}, {true, "https://foobar.com", "https://foobar.com"},
{false, false, "https://foobar.com", "https://bazbar.com"}, {false, "https://foobar.com", "https://bazbar.com"},
{true, false, "https://foobar.com", "https-so://name.foobar.com"}, {false, "https://foobar.com", "https-so://name.foobar.com"},
{true, false, "https-so://name.foobar.com", "https://foobar.com"}, {false, "https-so://name.foobar.com", "https://foobar.com"},
{true, true, "https-so://name.foobar.com", "https-so://name.foobar.com"}, {true, "https-so://name.foobar.com", "https-so://name.foobar.com"},
}; };
for (size_t i = 0; i < WTF_ARRAY_LENGTH(tests); ++i) { for (size_t i = 0; i < WTF_ARRAY_LENGTH(tests); ++i) {
...@@ -353,8 +352,6 @@ TEST_F(SecurityOriginTest, CanAccess) { ...@@ -353,8 +352,6 @@ TEST_F(SecurityOriginTest, CanAccess) {
RefPtr<SecurityOrigin> origin2 = RefPtr<SecurityOrigin> origin2 =
SecurityOrigin::createFromString(tests[i].origin2); SecurityOrigin::createFromString(tests[i].origin2);
EXPECT_EQ(tests[i].canAccess, origin1->canAccess(origin2.get())); EXPECT_EQ(tests[i].canAccess, origin1->canAccess(origin2.get()));
EXPECT_EQ(tests[i].canAccessCheckSuborigins,
origin1->canAccessCheckSuborigins(origin2.get()));
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment