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 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 2506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2887 } | 2846 } |
2888 | 2847 |
2889 void Document::disableEval(const String& errorMessage) | 2848 void Document::disableEval(const String& errorMessage) |
2890 { | 2849 { |
2891 if (!frame()) | 2850 if (!frame()) |
2892 return; | 2851 return; |
2893 | 2852 |
2894 frame()->script().disableEval(errorMessage); | 2853 frame()->script().disableEval(errorMessage); |
2895 } | 2854 } |
2896 | 2855 |
2897 bool Document::canNavigate(const Frame& targetFrame) | |
2898 { | |
2899 if (!m_frame) | |
2900 return false; | |
2901 | |
2902 // Frame-busting is generally allowed, but blocked for sandboxed frames lack
ing the 'allow-top-navigation' flag. | |
2903 if (!isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().top
()) | |
2904 return true; | |
2905 | |
2906 if (isSandboxed(SandboxNavigation)) { | |
2907 if (targetFrame.tree().isDescendantOf(m_frame)) | |
2908 return true; | |
2909 | |
2910 const char* reason = "The frame attempting navigation is sandboxed, and
is therefore disallowed from navigating its ancestors."; | |
2911 if (isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().
top()) | |
2912 reason = "The frame attempting navigation of the top-level window is
sandboxed, but the 'allow-top-navigation' flag is not set."; | |
2913 | |
2914 printNavigationErrorMessage(toLocalFrameTemporary(targetFrame), url(), r
eason); | |
2915 return false; | |
2916 } | |
2917 | |
2918 ASSERT(securityOrigin()); | |
2919 SecurityOrigin& origin = *securityOrigin(); | |
2920 | |
2921 // This is the normal case. A document can navigate its decendant frames, | |
2922 // or, more generally, a document can navigate a frame if the document is | |
2923 // in the same origin as any of that frame's ancestors (in the frame | |
2924 // hierarchy). | |
2925 // | |
2926 // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for | |
2927 // historical information about this security check. | |
2928 if (canAccessAncestor(origin, &targetFrame)) | |
2929 return true; | |
2930 | |
2931 // Top-level frames are easier to navigate than other frames because they | |
2932 // display their URLs in the address bar (in most browsers). However, there | |
2933 // are still some restrictions on navigation to avoid nuisance attacks. | |
2934 // Specifically, a document can navigate a top-level frame if that frame | |
2935 // opened the document or if the document is the same-origin with any of | |
2936 // the top-level frame's opener's ancestors (in the frame hierarchy). | |
2937 // | |
2938 // In both of these cases, the document performing the navigation is in | |
2939 // some way related to the frame being navigate (e.g., by the "opener" | |
2940 // and/or "parent" relation). Requiring some sort of relation prevents a | |
2941 // document from navigating arbitrary, unrelated top-level frames. | |
2942 if (!targetFrame.tree().parent()) { | |
2943 if (targetFrame == m_frame->loader().opener()) | |
2944 return true; | |
2945 | |
2946 // FIXME: We don't have access to RemoteFrame's opener yet. | |
2947 if (targetFrame.isLocalFrame() && canAccessAncestor(origin, toLocalFrame
(targetFrame).loader().opener())) | |
2948 return true; | |
2949 } | |
2950 | |
2951 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."); | |
2952 return false; | |
2953 } | |
2954 | |
2955 LocalFrame* Document::findUnsafeParentScrollPropagationBoundary() | |
2956 { | |
2957 LocalFrame* currentFrame = m_frame; | |
2958 Frame* ancestorFrame = currentFrame->tree().parent(); | |
2959 | |
2960 while (ancestorFrame) { | |
2961 // FIXME: We don't yet have access to a RemoteFrame's security origin. | |
2962 if (!ancestorFrame->isLocalFrame()) | |
2963 return currentFrame; | |
2964 if (!toLocalFrame(ancestorFrame)->document()->securityOrigin()->canAcces
s(securityOrigin())) | |
2965 return currentFrame; | |
2966 currentFrame = toLocalFrame(ancestorFrame); | |
2967 ancestorFrame = ancestorFrame->tree().parent(); | |
2968 } | |
2969 return 0; | |
2970 } | |
2971 | 2856 |
2972 void Document::didLoadAllImports() | 2857 void Document::didLoadAllImports() |
2973 { | 2858 { |
2974 if (!haveStylesheetsLoaded()) | 2859 if (!haveStylesheetsLoaded()) |
2975 return; | 2860 return; |
2976 if (!importLoader()) | 2861 if (!importLoader()) |
2977 styleResolverMayHaveChanged(); | 2862 styleResolverMayHaveChanged(); |
2978 didLoadAllScriptBlockingResources(); | 2863 didLoadAllScriptBlockingResources(); |
2979 } | 2864 } |
2980 | 2865 |
(...skipping 2892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5873 #ifndef NDEBUG | 5758 #ifndef NDEBUG |
5874 using namespace blink; | 5759 using namespace blink; |
5875 void showLiveDocumentInstances() | 5760 void showLiveDocumentInstances() |
5876 { | 5761 { |
5877 WeakDocumentSet& set = liveDocumentSet(); | 5762 WeakDocumentSet& set = liveDocumentSet(); |
5878 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); | 5763 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); |
5879 for (Document* document : set) | 5764 for (Document* document : set) |
5880 fprintf(stderr, "- Document %p URL: %s\n", document, document->url().str
ing().utf8().data()); | 5765 fprintf(stderr, "- Document %p URL: %s\n", document, document->url().str
ing().utf8().data()); |
5881 } | 5766 } |
5882 #endif | 5767 #endif |
OLD | NEW |