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

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: Address dcheng's comments Created 6 years 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 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 return toRenderPart(renderer)->widget(); 319 return toRenderPart(renderer)->widget();
320 } 320 }
321 321
322 static bool acceptsEditingFocus(const Element& element) 322 static bool acceptsEditingFocus(const Element& element)
323 { 323 {
324 ASSERT(element.hasEditableStyle()); 324 ASSERT(element.hasEditableStyle());
325 325
326 return element.document().frame() && element.rootEditableElement(); 326 return element.document().frame() && element.rootEditableElement();
327 } 327 }
328 328
329 static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, const Frame* targetFrame)
330 {
331 // targetFrame can be 0 when we're trying to navigate a top-level frame
332 // that has a 0 opener.
333 if (!targetFrame)
334 return false;
335
336 const bool isLocalActiveOrigin = activeSecurityOrigin.isLocal();
337 for (const Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree().parent()) {
338 // FIXME: SecurityOrigins need to be refactored to work with out-of-proc ess iframes.
339 // For now we prevent navigation between cross-process frames.
340 if (!ancestorFrame->isLocalFrame())
341 return false;
342
343 Document* ancestorDocument = toLocalFrame(ancestorFrame)->document();
344 // FIXME: Should be an ASSERT? Frames should alway have documents.
345 if (!ancestorDocument)
346 return true;
347
348 const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securit yOrigin();
349 if (activeSecurityOrigin.canAccess(ancestorSecurityOrigin))
350 return true;
351
352 // Allow file URL descendant navigation even when allowFileAccessFromFil eURLs is false.
353 // FIXME: It's a bit strange to special-case local origins here. Should we be doing
354 // something more general instead?
355 if (isLocalActiveOrigin && ancestorSecurityOrigin->isLocal())
356 return true;
357 }
358
359 return false;
360 }
361
362 static void printNavigationErrorMessage(const LocalFrame& frame, const KURL& act iveURL, const char* reason)
363 {
364 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";
365
366 // FIXME: should we print to the console of the document performing the navi gation instead?
367 frame.localDOMWindow()->printErrorMessage(message);
368 }
369
370 uint64_t Document::s_globalTreeVersion = 0; 329 uint64_t Document::s_globalTreeVersion = 0;
371 330
372 #ifndef NDEBUG 331 #ifndef NDEBUG
373 using WeakDocumentSet = WillBeHeapHashSet<RawPtrWillBeWeakMember<Document>>; 332 using WeakDocumentSet = WillBeHeapHashSet<RawPtrWillBeWeakMember<Document>>;
374 static WeakDocumentSet& liveDocumentSet() 333 static WeakDocumentSet& liveDocumentSet()
375 { 334 {
376 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WeakDocumentSet>, set, (adoptPtrW illBeNoop(new WeakDocumentSet()))); 335 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WeakDocumentSet>, set, (adoptPtrW illBeNoop(new WeakDocumentSet())));
377 return *set; 336 return *set;
378 } 337 }
379 #endif 338 #endif
(...skipping 2495 matching lines...) Expand 10 before | Expand all | Expand 10 after
2875 } 2834 }
2876 2835
2877 void Document::disableEval(const String& errorMessage) 2836 void Document::disableEval(const String& errorMessage)
2878 { 2837 {
2879 if (!frame()) 2838 if (!frame())
2880 return; 2839 return;
2881 2840
2882 frame()->script().disableEval(errorMessage); 2841 frame()->script().disableEval(errorMessage);
2883 } 2842 }
2884 2843
2885 bool Document::canNavigate(const Frame& targetFrame)
2886 {
2887 if (!m_frame)
2888 return false;
2889
2890 // Frame-busting is generally allowed, but blocked for sandboxed frames lack ing the 'allow-top-navigation' flag.
2891 if (!isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().top ())
2892 return true;
2893
2894 if (isSandboxed(SandboxNavigation)) {
2895 if (targetFrame.tree().isDescendantOf(m_frame))
2896 return true;
2897
2898 const char* reason = "The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors.";
2899 if (isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree(). top())
2900 reason = "The frame attempting navigation of the top-level window is sandboxed, but the 'allow-top-navigation' flag is not set.";
2901
2902 printNavigationErrorMessage(toLocalFrameTemporary(targetFrame), url(), r eason);
2903 return false;
2904 }
2905
2906 ASSERT(securityOrigin());
2907 SecurityOrigin& origin = *securityOrigin();
2908
2909 // This is the normal case. A document can navigate its decendant frames,
2910 // or, more generally, a document can navigate a frame if the document is
2911 // in the same origin as any of that frame's ancestors (in the frame
2912 // hierarchy).
2913 //
2914 // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for
2915 // historical information about this security check.
2916 if (canAccessAncestor(origin, &targetFrame))
2917 return true;
2918
2919 // Top-level frames are easier to navigate than other frames because they
2920 // display their URLs in the address bar (in most browsers). However, there
2921 // are still some restrictions on navigation to avoid nuisance attacks.
2922 // Specifically, a document can navigate a top-level frame if that frame
2923 // opened the document or if the document is the same-origin with any of
2924 // the top-level frame's opener's ancestors (in the frame hierarchy).
2925 //
2926 // In both of these cases, the document performing the navigation is in
2927 // some way related to the frame being navigate (e.g., by the "opener"
2928 // and/or "parent" relation). Requiring some sort of relation prevents a
2929 // document from navigating arbitrary, unrelated top-level frames.
2930 if (!targetFrame.tree().parent()) {
2931 if (targetFrame == m_frame->loader().opener())
2932 return true;
2933
2934 // FIXME: We don't have access to RemoteFrame's opener yet.
2935 if (targetFrame.isLocalFrame() && canAccessAncestor(origin, toLocalFrame (targetFrame).loader().opener()))
2936 return true;
2937 }
2938
2939 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.");
2940 return false;
2941 }
2942
2943 LocalFrame* Document::findUnsafeParentScrollPropagationBoundary()
2944 {
2945 LocalFrame* currentFrame = m_frame;
2946 Frame* ancestorFrame = currentFrame->tree().parent();
2947
2948 while (ancestorFrame) {
2949 // FIXME: We don't yet have access to a RemoteFrame's security origin.
2950 if (!ancestorFrame->isLocalFrame())
2951 return currentFrame;
2952 if (!toLocalFrame(ancestorFrame)->document()->securityOrigin()->canAcces s(securityOrigin()))
2953 return currentFrame;
2954 currentFrame = toLocalFrame(ancestorFrame);
2955 ancestorFrame = ancestorFrame->tree().parent();
2956 }
2957 return 0;
2958 }
2959 2844
2960 void Document::didLoadAllImports() 2845 void Document::didLoadAllImports()
2961 { 2846 {
2962 if (!haveStylesheetsLoaded()) 2847 if (!haveStylesheetsLoaded())
2963 return; 2848 return;
2964 if (!importLoader()) 2849 if (!importLoader())
2965 styleResolverMayHaveChanged(); 2850 styleResolverMayHaveChanged();
2966 didLoadAllScriptBlockingResources(); 2851 didLoadAllScriptBlockingResources();
2967 } 2852 }
2968 2853
(...skipping 2884 matching lines...) Expand 10 before | Expand all | Expand 10 after
5853 #ifndef NDEBUG 5738 #ifndef NDEBUG
5854 using namespace blink; 5739 using namespace blink;
5855 void showLiveDocumentInstances() 5740 void showLiveDocumentInstances()
5856 { 5741 {
5857 WeakDocumentSet& set = liveDocumentSet(); 5742 WeakDocumentSet& set = liveDocumentSet();
5858 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); 5743 fprintf(stderr, "There are %u documents currently alive:\n", set.size());
5859 for (Document* document : set) 5744 for (Document* document : set)
5860 fprintf(stderr, "- Document %p URL: %s\n", document, document->url().str ing().utf8().data()); 5745 fprintf(stderr, "- Document %p URL: %s\n", document, document->url().str ing().utf8().data());
5861 } 5746 }
5862 #endif 5747 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698