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

Unified Diff: Source/core/frame/Frame.cpp

Issue 799923006: Make canNavigate() OOPI-friendly (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Null-check in History.cpp Created 5 years, 11 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
« no previous file with comments | « Source/core/frame/Frame.h ('k') | Source/core/frame/FrameView.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/frame/Frame.cpp
diff --git a/Source/core/frame/Frame.cpp b/Source/core/frame/Frame.cpp
index b121c1ac38e139e876ab97d5fde16cd72e4f50db..c84121d3b075c7109510c707480acadf2d4fef66 100644
--- a/Source/core/frame/Frame.cpp
+++ b/Source/core/frame/Frame.cpp
@@ -150,6 +150,104 @@ ChromeClient& Frame::chromeClient() const
return emptyChromeClient();
}
+Frame* Frame::findFrameForNavigation(const AtomicString& name, Frame& activeFrame)
+{
+ Frame* frame = tree().find(name);
+ if (!frame || !activeFrame.canNavigate(*frame))
+ return nullptr;
+ return frame;
+}
+
+static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, const Frame* targetFrame)
+{
+ // targetFrame can be 0 when we're trying to navigate a top-level frame
+ // that has a 0 opener.
+ if (!targetFrame)
+ return false;
+
+ const bool isLocalActiveOrigin = activeSecurityOrigin.isLocal();
+ for (const Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree().parent()) {
+ const SecurityOrigin* ancestorSecurityOrigin = ancestorFrame->securityContext()->securityOrigin();
+ if (activeSecurityOrigin.canAccess(ancestorSecurityOrigin))
+ return true;
+
+ // Allow file URL descendant navigation even when allowFileAccessFromFileURLs is false.
+ // FIXME: It's a bit strange to special-case local origins here. Should we be doing
+ // something more general instead?
+ if (isLocalActiveOrigin && ancestorSecurityOrigin->isLocal())
+ return true;
+ }
+
+ return false;
+}
+
+bool Frame::canNavigate(const Frame& targetFrame)
+{
+ // Frame-busting is generally allowed, but blocked for sandboxed frames lacking the 'allow-top-navigation' flag.
+ if (!securityContext()->isSandboxed(SandboxTopNavigation) && targetFrame == tree().top())
+ return true;
+
+ if (securityContext()->isSandboxed(SandboxNavigation)) {
+ if (targetFrame.tree().isDescendantOf(this))
+ return true;
+
+ const char* reason = "The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors.";
+ if (securityContext()->isSandboxed(SandboxTopNavigation) && targetFrame == tree().top())
+ reason = "The frame attempting navigation of the top-level window is sandboxed, but the 'allow-top-navigation' flag is not set.";
+
+ printNavigationErrorMessage(targetFrame, reason);
+ return false;
+ }
+
+ ASSERT(securityContext()->securityOrigin());
+ SecurityOrigin& origin = *securityContext()->securityOrigin();
+
+ // This is the normal case. A document can navigate its decendant frames,
+ // or, more generally, a document can navigate a frame if the document is
+ // in the same origin as any of that frame's ancestors (in the frame
+ // hierarchy).
+ //
+ // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for
+ // historical information about this security check.
+ if (canAccessAncestor(origin, &targetFrame))
+ return true;
+
+ // Top-level frames are easier to navigate than other frames because they
+ // display their URLs in the address bar (in most browsers). However, there
+ // are still some restrictions on navigation to avoid nuisance attacks.
+ // Specifically, a document can navigate a top-level frame if that frame
+ // opened the document or if the document is the same-origin with any of
+ // the top-level frame's opener's ancestors (in the frame hierarchy).
+ //
+ // In both of these cases, the document performing the navigation is in
+ // some way related to the frame being navigate (e.g., by the "opener"
+ // and/or "parent" relation). Requiring some sort of relation prevents a
+ // document from navigating arbitrary, unrelated top-level frames.
+ if (!targetFrame.tree().parent()) {
+ if (targetFrame == client()->opener())
+ return true;
+ if (canAccessAncestor(origin, targetFrame.client()->opener()))
+ return true;
+ }
+
+ printNavigationErrorMessage(targetFrame, "The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.");
+ return false;
+}
+
+Frame* Frame::findUnsafeParentScrollPropagationBoundary()
+{
+ Frame* currentFrame = this;
+ Frame* ancestorFrame = tree().parent();
+
+ while (ancestorFrame) {
+ if (!ancestorFrame->securityContext()->securityOrigin()->canAccess(securityContext()->securityOrigin()))
+ return currentFrame;
+ currentFrame = ancestorFrame;
+ ancestorFrame = ancestorFrame->tree().parent();
+ }
+ return nullptr;
+}
+
RenderPart* Frame::ownerRenderer() const
{
if (!deprecatedLocalOwner())
« no previous file with comments | « Source/core/frame/Frame.h ('k') | Source/core/frame/FrameView.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698