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

Side by Side Diff: Source/core/dom/Document.cpp

Issue 799923006: Make canNavigate() OOPI-friendly (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r ights reserved. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r ights reserved.
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. 8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) 9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. 10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 return toRenderPart(renderer)->widget(); 320 return toRenderPart(renderer)->widget();
321 } 321 }
322 322
323 static bool acceptsEditingFocus(const Element& element) 323 static bool acceptsEditingFocus(const Element& element)
324 { 324 {
325 ASSERT(element.hasEditableStyle()); 325 ASSERT(element.hasEditableStyle());
326 326
327 return element.document().frame() && element.rootEditableElement(); 327 return element.document().frame() && element.rootEditableElement();
328 } 328 }
329 329
330 static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, const Frame* targetFrame)
331 {
332 // targetFrame can be 0 when we're trying to navigate a top-level frame
333 // that has a 0 opener.
334 if (!targetFrame)
335 return false;
336
337 const bool isLocalActiveOrigin = activeSecurityOrigin.isLocal();
338 for (const Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree().parent()) {
339 // FIXME: SecurityOrigins need to be refactored to work with out-of-proc ess iframes.
340 // For now we prevent navigation between cross-process frames.
341 if (!ancestorFrame->isLocalFrame())
342 return false;
343
344 Document* ancestorDocument = toLocalFrame(ancestorFrame)->document();
345 // FIXME: Should be an ASSERT? Frames should alway have documents.
346 if (!ancestorDocument)
347 return true;
348
349 const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securit yOrigin();
350 if (activeSecurityOrigin.canAccess(ancestorSecurityOrigin))
351 return true;
352
353 // Allow file URL descendant navigation even when allowFileAccessFromFil eURLs is false.
354 // FIXME: It's a bit strange to special-case local origins here. Should we be doing
355 // something more general instead?
356 if (isLocalActiveOrigin && ancestorSecurityOrigin->isLocal())
357 return true;
358 }
359
360 return false;
361 }
362
363 static void printNavigationErrorMessage(const LocalFrame& frame, const KURL& act iveURL, const char* reason)
364 {
365 String message = "Unsafe JavaScript attempt to initiate navigation for frame with URL '" + frame.document()->url().string() + "' from frame with URL '" + ac tiveURL.string() + "'. " + reason + "\n";
366
367 // FIXME: should we print to the console of the document performing the navi gation instead?
368 frame.localDOMWindow()->printErrorMessage(message);
369 }
370
371 uint64_t Document::s_globalTreeVersion = 0; 330 uint64_t Document::s_globalTreeVersion = 0;
372 331
373 #ifndef NDEBUG 332 #ifndef NDEBUG
374 using WeakDocumentSet = WillBeHeapHashSet<RawPtrWillBeWeakMember<Document>>; 333 using WeakDocumentSet = WillBeHeapHashSet<RawPtrWillBeWeakMember<Document>>;
375 static WeakDocumentSet& liveDocumentSet() 334 static WeakDocumentSet& liveDocumentSet()
376 { 335 {
377 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WeakDocumentSet>, set, (adoptPtrW illBeNoop(new WeakDocumentSet()))); 336 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WeakDocumentSet>, set, (adoptPtrW illBeNoop(new WeakDocumentSet())));
378 return *set; 337 return *set;
379 } 338 }
380 #endif 339 #endif
(...skipping 2504 matching lines...) Expand 10 before | Expand all | Expand 10 after
2885 } 2844 }
2886 2845
2887 void Document::disableEval(const String& errorMessage) 2846 void Document::disableEval(const String& errorMessage)
2888 { 2847 {
2889 if (!frame()) 2848 if (!frame())
2890 return; 2849 return;
2891 2850
2892 frame()->script().disableEval(errorMessage); 2851 frame()->script().disableEval(errorMessage);
2893 } 2852 }
2894 2853
2895 bool Document::canNavigate(const Frame& targetFrame)
2896 {
2897 if (!m_frame)
2898 return false;
2899
2900 // Frame-busting is generally allowed, but blocked for sandboxed frames lack ing the 'allow-top-navigation' flag.
2901 if (!isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().top ())
2902 return true;
2903
2904 if (isSandboxed(SandboxNavigation)) {
2905 if (targetFrame.tree().isDescendantOf(m_frame))
2906 return true;
2907
2908 const char* reason = "The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors.";
2909 if (isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree(). top())
2910 reason = "The frame attempting navigation of the top-level window is sandboxed, but the 'allow-top-navigation' flag is not set.";
2911
2912 printNavigationErrorMessage(toLocalFrameTemporary(targetFrame), url(), r eason);
2913 return false;
2914 }
2915
2916 ASSERT(securityOrigin());
2917 SecurityOrigin& origin = *securityOrigin();
2918
2919 // This is the normal case. A document can navigate its decendant frames,
2920 // or, more generally, a document can navigate a frame if the document is
2921 // in the same origin as any of that frame's ancestors (in the frame
2922 // hierarchy).
2923 //
2924 // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for
2925 // historical information about this security check.
2926 if (canAccessAncestor(origin, &targetFrame))
2927 return true;
2928
2929 // Top-level frames are easier to navigate than other frames because they
2930 // display their URLs in the address bar (in most browsers). However, there
2931 // are still some restrictions on navigation to avoid nuisance attacks.
2932 // Specifically, a document can navigate a top-level frame if that frame
2933 // opened the document or if the document is the same-origin with any of
2934 // the top-level frame's opener's ancestors (in the frame hierarchy).
2935 //
2936 // In both of these cases, the document performing the navigation is in
2937 // some way related to the frame being navigate (e.g., by the "opener"
2938 // and/or "parent" relation). Requiring some sort of relation prevents a
2939 // document from navigating arbitrary, unrelated top-level frames.
2940 if (!targetFrame.tree().parent()) {
2941 if (targetFrame == m_frame->loader().opener())
2942 return true;
2943
2944 // FIXME: We don't have access to RemoteFrame's opener yet.
2945 if (targetFrame.isLocalFrame() && canAccessAncestor(origin, toLocalFrame (targetFrame).loader().opener()))
2946 return true;
2947 }
2948
2949 printNavigationErrorMessage(toLocalFrameTemporary(targetFrame), url(), "The frame attempting navigation is neither same-origin with the target, nor is it th e target's parent or opener.");
2950 return false;
2951 }
2952
2953 LocalFrame* Document::findUnsafeParentScrollPropagationBoundary()
2954 {
2955 LocalFrame* currentFrame = m_frame;
2956 Frame* ancestorFrame = currentFrame->tree().parent();
2957
2958 while (ancestorFrame) {
2959 // FIXME: We don't yet have access to a RemoteFrame's security origin.
2960 if (!ancestorFrame->isLocalFrame())
2961 return currentFrame;
2962 if (!toLocalFrame(ancestorFrame)->document()->securityOrigin()->canAcces s(securityOrigin()))
2963 return currentFrame;
2964 currentFrame = toLocalFrame(ancestorFrame);
2965 ancestorFrame = ancestorFrame->tree().parent();
2966 }
2967 return 0;
2968 }
2969 2854
2970 void Document::didLoadAllImports() 2855 void Document::didLoadAllImports()
2971 { 2856 {
2972 if (!haveStylesheetsLoaded()) 2857 if (!haveStylesheetsLoaded())
2973 return; 2858 return;
2974 if (!importLoader()) 2859 if (!importLoader())
2975 styleResolverMayHaveChanged(); 2860 styleResolverMayHaveChanged();
2976 didLoadAllScriptBlockingResources(); 2861 didLoadAllScriptBlockingResources();
2977 } 2862 }
2978 2863
(...skipping 2892 matching lines...) Expand 10 before | Expand all | Expand 10 after
5871 #ifndef NDEBUG 5756 #ifndef NDEBUG
5872 using namespace blink; 5757 using namespace blink;
5873 void showLiveDocumentInstances() 5758 void showLiveDocumentInstances()
5874 { 5759 {
5875 WeakDocumentSet& set = liveDocumentSet(); 5760 WeakDocumentSet& set = liveDocumentSet();
5876 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); 5761 fprintf(stderr, "There are %u documents currently alive:\n", set.size());
5877 for (Document* document : set) 5762 for (Document* document : set)
5878 fprintf(stderr, "- Document %p URL: %s\n", document, document->url().str ing().utf8().data()); 5763 fprintf(stderr, "- Document %p URL: %s\n", document, document->url().str ing().utf8().data());
5879 } 5764 }
5880 #endif 5765 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698