| OLD | NEW |
| 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 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 return toRenderPart(renderer)->widget(); | 318 return toRenderPart(renderer)->widget(); |
| 319 } | 319 } |
| 320 | 320 |
| 321 static bool acceptsEditingFocus(const Element& element) | 321 static bool acceptsEditingFocus(const Element& element) |
| 322 { | 322 { |
| 323 ASSERT(element.hasEditableStyle()); | 323 ASSERT(element.hasEditableStyle()); |
| 324 | 324 |
| 325 return element.document().frame() && element.rootEditableElement(); | 325 return element.document().frame() && element.rootEditableElement(); |
| 326 } | 326 } |
| 327 | 327 |
| 328 static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, const
Frame* targetFrame) | |
| 329 { | |
| 330 // targetFrame can be 0 when we're trying to navigate a top-level frame | |
| 331 // that has a 0 opener. | |
| 332 if (!targetFrame) | |
| 333 return false; | |
| 334 | |
| 335 const bool isLocalActiveOrigin = activeSecurityOrigin.isLocal(); | |
| 336 for (const Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame
= ancestorFrame->tree().parent()) { | |
| 337 // FIXME: SecurityOrigins need to be refactored to work with out-of-proc
ess iframes. | |
| 338 // For now we prevent navigation between cross-process frames. | |
| 339 if (!ancestorFrame->isLocalFrame()) | |
| 340 return false; | |
| 341 | |
| 342 Document* ancestorDocument = toLocalFrame(ancestorFrame)->document(); | |
| 343 // FIXME: Should be an ASSERT? Frames should alway have documents. | |
| 344 if (!ancestorDocument) | |
| 345 return true; | |
| 346 | |
| 347 const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securit
yOrigin(); | |
| 348 if (activeSecurityOrigin.canAccess(ancestorSecurityOrigin)) | |
| 349 return true; | |
| 350 | |
| 351 // Allow file URL descendant navigation even when allowFileAccessFromFil
eURLs is false. | |
| 352 // FIXME: It's a bit strange to special-case local origins here. Should
we be doing | |
| 353 // something more general instead? | |
| 354 if (isLocalActiveOrigin && ancestorSecurityOrigin->isLocal()) | |
| 355 return true; | |
| 356 } | |
| 357 | |
| 358 return false; | |
| 359 } | |
| 360 | |
| 361 static void printNavigationErrorMessage(const LocalFrame& frame, const KURL& act
iveURL, const char* reason) | |
| 362 { | |
| 363 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"; | |
| 364 | |
| 365 // FIXME: should we print to the console of the document performing the navi
gation instead? | |
| 366 frame.localDOMWindow()->printErrorMessage(message); | |
| 367 } | |
| 368 | |
| 369 uint64_t Document::s_globalTreeVersion = 0; | 328 uint64_t Document::s_globalTreeVersion = 0; |
| 370 | 329 |
| 371 #ifndef NDEBUG | 330 #ifndef NDEBUG |
| 372 using WeakDocumentSet = WillBeHeapHashSet<RawPtrWillBeWeakMember<Document>>; | 331 using WeakDocumentSet = WillBeHeapHashSet<RawPtrWillBeWeakMember<Document>>; |
| 373 static WeakDocumentSet& liveDocumentSet() | 332 static WeakDocumentSet& liveDocumentSet() |
| 374 { | 333 { |
| 375 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WeakDocumentSet>, set, (adoptPtrW
illBeNoop(new WeakDocumentSet()))); | 334 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WeakDocumentSet>, set, (adoptPtrW
illBeNoop(new WeakDocumentSet()))); |
| 376 return *set; | 335 return *set; |
| 377 } | 336 } |
| 378 #endif | 337 #endif |
| (...skipping 2496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 2878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5847 #ifndef NDEBUG | 5732 #ifndef NDEBUG |
| 5848 using namespace blink; | 5733 using namespace blink; |
| 5849 void showLiveDocumentInstances() | 5734 void showLiveDocumentInstances() |
| 5850 { | 5735 { |
| 5851 WeakDocumentSet& set = liveDocumentSet(); | 5736 WeakDocumentSet& set = liveDocumentSet(); |
| 5852 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); | 5737 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); |
| 5853 for (Document* document : set) | 5738 for (Document* document : set) |
| 5854 fprintf(stderr, "- Document %p URL: %s\n", document, document->url().str
ing().utf8().data()); | 5739 fprintf(stderr, "- Document %p URL: %s\n", document, document->url().str
ing().utf8().data()); |
| 5855 } | 5740 } |
| 5856 #endif | 5741 #endif |
| OLD | NEW |