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

Unified Diff: third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp

Issue 2706923002: Rework security checks to be based on Window rather than Frame. (Closed)
Patch Set: Address review comments. 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/bindings/core/v8/BindingSecurity.cpp
diff --git a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp
index 516ef4dff5498d95b703de67ff7f23e7350fcaca..4217b26d89e7cbce8fbf68ae42a3e48245183ec6 100644
--- a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp
@@ -32,7 +32,10 @@
#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/V8Binding.h"
+#include "bindings/core/v8/V8Location.h"
+#include "bindings/core/v8/V8Window.h"
#include "core/dom/Document.h"
+#include "core/frame/DOMWindow.h"
#include "core/frame/LocalDOMWindow.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Location.h"
@@ -45,9 +48,8 @@ namespace blink {
namespace {
-bool canAccessFrameInternal(const LocalDOMWindow* accessingWindow,
- const SecurityOrigin* targetFrameOrigin,
- const DOMWindow* targetWindow) {
+bool canAccessWindowInternal(const LocalDOMWindow* accessingWindow,
+ const DOMWindow* targetWindow) {
SECURITY_CHECK(!(targetWindow && targetWindow->frame()) ||
targetWindow == targetWindow->frame()->domWindow());
@@ -60,11 +62,14 @@ bool canAccessFrameInternal(const LocalDOMWindow* accessingWindow,
const SecurityOrigin* accessingOrigin =
accessingWindow->document()->getSecurityOrigin();
- if (!accessingOrigin->canAccessCheckSuborigins(targetFrameOrigin))
+ const LocalDOMWindow* localTargetWindow = toLocalDOMWindow(targetWindow);
+ if (!accessingOrigin->canAccessCheckSuborigins(
+ localTargetWindow->document()->getSecurityOrigin())) {
return false;
+ }
// Notify the loader's client if the initial document has been accessed.
- LocalFrame* targetFrame = toLocalDOMWindow(targetWindow)->frame();
+ LocalFrame* targetFrame = localTargetWindow->frame();
if (targetFrame &&
targetFrame->loader().stateMachine()->isDisplayingInitialEmptyDocument())
targetFrame->loader().didAccessInitialDocument();
@@ -72,11 +77,10 @@ bool canAccessFrameInternal(const LocalDOMWindow* accessingWindow,
return true;
}
-bool canAccessFrame(const LocalDOMWindow* accessingWindow,
- const SecurityOrigin* targetFrameOrigin,
- const DOMWindow* targetWindow,
- ExceptionState& exceptionState) {
- if (canAccessFrameInternal(accessingWindow, targetFrameOrigin, targetWindow))
+bool canAccessWindow(const LocalDOMWindow* accessingWindow,
+ const DOMWindow* targetWindow,
+ ExceptionState& exceptionState) {
+ if (canAccessWindowInternal(accessingWindow, targetWindow))
return true;
if (targetWindow)
@@ -86,11 +90,10 @@ bool canAccessFrame(const LocalDOMWindow* accessingWindow,
return false;
}
-bool canAccessFrame(const LocalDOMWindow* accessingWindow,
- SecurityOrigin* targetFrameOrigin,
- const DOMWindow* targetWindow,
- BindingSecurity::ErrorReportOption reportingOption) {
- if (canAccessFrameInternal(accessingWindow, targetFrameOrigin, targetWindow))
+bool canAccessWindow(const LocalDOMWindow* accessingWindow,
+ const DOMWindow* targetWindow,
+ BindingSecurity::ErrorReportOption reportingOption) {
+ if (canAccessWindowInternal(accessingWindow, targetWindow))
return true;
if (accessingWindow && targetWindow &&
@@ -100,73 +103,48 @@ bool canAccessFrame(const LocalDOMWindow* accessingWindow,
return false;
}
+DOMWindow* findWindow(v8::Isolate* isolate,
+ const WrapperTypeInfo* type,
+ v8::Local<v8::Object> host) {
+ if (V8Window::wrapperTypeInfo.equals(type))
haraken 2017/03/07 08:53:57 Previously we were using findInstanceInPrototypeCh
dcheng 2017/03/07 09:06:46 Originally, we didn't set the internal fields of t
+ return V8Window::toImpl(host);
+
+ if (V8Location::wrapperTypeInfo.equals(type))
+ return V8Location::toImpl(host)->domWindow();
+
+ // This function can handle only those types listed above.
+ NOTREACHED();
+ return nullptr;
+}
+
} // namespace
bool BindingSecurity::shouldAllowAccessTo(const LocalDOMWindow* accessingWindow,
const DOMWindow* target,
ExceptionState& exceptionState) {
DCHECK(target);
- const Frame* frame = target->frame();
- if (!frame || !frame->securityContext())
- return false;
- return canAccessFrame(accessingWindow,
- frame->securityContext()->getSecurityOrigin(), target,
- exceptionState);
+ return canAccessWindow(accessingWindow, target, exceptionState);
}
bool BindingSecurity::shouldAllowAccessTo(const LocalDOMWindow* accessingWindow,
const DOMWindow* target,
ErrorReportOption reportingOption) {
DCHECK(target);
- const Frame* frame = target->frame();
- if (!frame || !frame->securityContext())
- return false;
- return canAccessFrame(accessingWindow,
- frame->securityContext()->getSecurityOrigin(), target,
- reportingOption);
-}
-
-bool BindingSecurity::shouldAllowAccessTo(const LocalDOMWindow* accessingWindow,
- const EventTarget* target,
- ExceptionState& exceptionState) {
- DCHECK(target);
- const DOMWindow* window = target->toDOMWindow();
- if (!window) {
- // We only need to check the access to Window objects which are
- // cross-origin accessible. If it's not a Window, the object's
- // origin must always be the same origin (or it already leaked).
- return true;
- }
- const Frame* frame = window->frame();
- if (!frame || !frame->securityContext())
- return false;
- return canAccessFrame(accessingWindow,
- frame->securityContext()->getSecurityOrigin(), window,
- exceptionState);
+ return canAccessWindow(accessingWindow, target, reportingOption);
}
bool BindingSecurity::shouldAllowAccessTo(const LocalDOMWindow* accessingWindow,
const Location* target,
ExceptionState& exceptionState) {
DCHECK(target);
- const Frame* frame = target->frame();
- if (!frame || !frame->securityContext())
- return false;
- return canAccessFrame(accessingWindow,
- frame->securityContext()->getSecurityOrigin(),
- frame->domWindow(), exceptionState);
+ return canAccessWindow(accessingWindow, target->domWindow(), exceptionState);
}
bool BindingSecurity::shouldAllowAccessTo(const LocalDOMWindow* accessingWindow,
const Location* target,
ErrorReportOption reportingOption) {
DCHECK(target);
- const Frame* frame = target->frame();
- if (!frame || !frame->securityContext())
- return false;
- return canAccessFrame(accessingWindow,
- frame->securityContext()->getSecurityOrigin(),
- frame->domWindow(), reportingOption);
+ return canAccessWindow(accessingWindow, target->domWindow(), reportingOption);
}
bool BindingSecurity::shouldAllowAccessTo(const LocalDOMWindow* accessingWindow,
@@ -174,8 +152,8 @@ bool BindingSecurity::shouldAllowAccessTo(const LocalDOMWindow* accessingWindow,
ExceptionState& exceptionState) {
if (!target)
return false;
- return canAccessFrame(accessingWindow, target->document().getSecurityOrigin(),
- target->document().domWindow(), exceptionState);
+ return canAccessWindow(accessingWindow, target->document().domWindow(),
+ exceptionState);
}
bool BindingSecurity::shouldAllowAccessTo(const LocalDOMWindow* accessingWindow,
@@ -183,8 +161,8 @@ bool BindingSecurity::shouldAllowAccessTo(const LocalDOMWindow* accessingWindow,
ErrorReportOption reportingOption) {
if (!target)
return false;
- return canAccessFrame(accessingWindow, target->document().getSecurityOrigin(),
- target->document().domWindow(), reportingOption);
+ return canAccessWindow(accessingWindow, target->document().domWindow(),
+ reportingOption);
}
bool BindingSecurity::shouldAllowAccessToFrame(
@@ -193,9 +171,7 @@ bool BindingSecurity::shouldAllowAccessToFrame(
ExceptionState& exceptionState) {
if (!target || !target->securityContext())
return false;
- return canAccessFrame(accessingWindow,
- target->securityContext()->getSecurityOrigin(),
- target->domWindow(), exceptionState);
+ return canAccessWindow(accessingWindow, target->domWindow(), exceptionState);
}
bool BindingSecurity::shouldAllowAccessToFrame(
@@ -204,25 +180,7 @@ bool BindingSecurity::shouldAllowAccessToFrame(
ErrorReportOption reportingOption) {
if (!target || !target->securityContext())
return false;
- return canAccessFrame(accessingWindow,
- target->securityContext()->getSecurityOrigin(),
- target->domWindow(), reportingOption);
-}
-
-bool BindingSecurity::shouldAllowAccessToDetachedWindow(
- const LocalDOMWindow* accessingWindow,
- const DOMWindow* target,
- ExceptionState& exceptionState) {
- CHECK(target && !target->frame())
- << "This version of shouldAllowAccessToFrame() must be used only for "
- << "detached windows.";
- if (!target->isLocalDOMWindow())
- return false;
- Document* document = toLocalDOMWindow(target)->document();
- if (!document)
- return false;
- return canAccessFrame(accessingWindow, document->getSecurityOrigin(), target,
- exceptionState);
+ return canAccessWindow(accessingWindow, target->domWindow(), reportingOption);
}
bool BindingSecurity::shouldAllowNamedAccessTo(const DOMWindow* accessingWindow,
@@ -253,22 +211,20 @@ bool BindingSecurity::shouldAllowNamedAccessTo(const DOMWindow* accessingWindow,
}
void BindingSecurity::failedAccessCheckFor(v8::Isolate* isolate,
- const Frame* target) {
- // TODO(dcheng): See if this null check can be removed or hoisted to a
- // different location.
- if (!target)
- return;
-
- DOMWindow* targetWindow = target->domWindow();
+ const WrapperTypeInfo* type,
+ v8::Local<v8::Object> host) {
haraken 2017/03/07 08:53:57 host => holder
dcheng 2017/03/07 09:06:46 Done.
+ DOMWindow* target = findWindow(isolate, type, host);
+ // Failing to find a target means something is wrong. Failing to throw an
+ // exception could be a security issue, so just crash.
+ CHECK(target);
// TODO(dcheng): Add ContextType, interface name, and property name as
// arguments, so the generated exception can be more descriptive.
ExceptionState exceptionState(isolate, ExceptionState::UnknownContext,
nullptr, nullptr);
exceptionState.throwSecurityError(
- targetWindow->sanitizedCrossDomainAccessErrorMessage(
- currentDOMWindow(isolate)),
- targetWindow->crossDomainAccessErrorMessage(currentDOMWindow(isolate)));
+ target->sanitizedCrossDomainAccessErrorMessage(currentDOMWindow(isolate)),
+ target->crossDomainAccessErrorMessage(currentDOMWindow(isolate)));
}
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698