Changeset 28225 in webkit


Ignore:
Timestamp:
Nov 29, 2007 9:20:39 PM (16 years ago)
Author:
weinig@apple.com
Message:

Reviewed by Oliver.

Additional fix for <rdar://problem/5592988> / http://bugs.webkit.org/show_bug.cgi?id=15936

  • More closely match IE's policy for frame navigation.
  • bindings/js/kjs_window.cpp: (KJS::WindowProtoFuncOpen::callAsFunction):
  • loader/FrameLoader.cpp: (WebCore::FrameLoader::shouldAllowNavigation):
  • page/FrameTree.cpp: (WebCore::FrameTree::top):
  • page/FrameTree.h:
Location:
trunk/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r28224 r28225  
     12007-11-29  Sam Weinig  <sam@webkit.org>
     2
     3        Reviewed by Oliver.
     4
     5        Additional fix for <rdar://problem/5592988> / http://bugs.webkit.org/show_bug.cgi?id=15936
     6        - More closely match IE's policy for frame navigation.
     7
     8        * bindings/js/kjs_window.cpp:
     9        (KJS::WindowProtoFuncOpen::callAsFunction):
     10        * loader/FrameLoader.cpp:
     11        (WebCore::FrameLoader::shouldAllowNavigation):
     12        * page/FrameTree.cpp:
     13        (WebCore::FrameTree::top):
     14        * page/FrameTree.h:
     15
    1162007-11-29  Dan Bernstein  <mitz@apple.com>
    217
  • trunk/WebCore/bindings/js/kjs_window.cpp

    r28110 r28225  
    13051305    if (!frame)
    13061306        return jsUndefined();
     1307    Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
     1308    if (!activeFrame)
     1309        return  jsUndefined();
    13071310
    13081311    Page* page = frame->page();
     
    13161319        return jsUndefined();
    13171320
    1318     // Get the target frame for the special cases of _top and _parent
    1319     if (frameName == "_top")
    1320         while (frame->tree()->parent())
    1321               frame = frame->tree()->parent();
    1322     else if (frameName == "_parent")
    1323         if (frame->tree()->parent())
    1324             frame = frame->tree()->parent();
    1325 
    1326     // In those cases, we can schedule a location change right now and return early
    1327     if (frameName == "_top" || frameName == "_parent") {
     1321    // Get the target frame for the special cases of _top and _parent.  In those
     1322    // cases, we can schedule a location change right now and return early.
     1323    bool topOrParent = false;
     1324    if (frameName == "_top") {
     1325        frame = frame->tree()->top();
     1326        topOrParent = true;
     1327    } else if (frameName == "_parent") {
     1328        if (Frame* parent = frame->tree()->parent())
     1329            frame = parent;
     1330        if (!activeFrame->loader()->shouldAllowNavigation(frame))
     1331            return jsUndefined();
     1332        topOrParent = true;
     1333    }
     1334    if (topOrParent) {
    13281335        String completedURL;
    1329         Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
    1330         if (!urlString.isEmpty() && activeFrame)
     1336        if (!urlString.isEmpty())
    13311337            completedURL = activeFrame->document()->completeURL(urlString);
    13321338
  • trunk/WebCore/loader/FrameLoader.cpp

    r28056 r28225  
    23092309bool FrameLoader::shouldAllowNavigation(Frame* targetFrame) const
    23102310{
    2311     // This function prevents these exploits:
    2312     // <rdar://problem/3715785> multiple frame injection vulnerability reported by Secunia, affects almost all browsers
    2313     // http://bugs.webkit.org/show_bug.cgi?id=15936 Overly permissive frame navigation allows password theft
    2314 
    2315     // Allow if there is no specific target.
     2311    // The navigation change is safe if the active frame is:
     2312    //   - in the same security origin as the target or one of the target's ancestors
     2313    // Or the target frame is:
     2314    //   - a top-level frame in the frame hierarchy
     2315
    23162316    if (!targetFrame)
    23172317        return true;
     2318
    23182319    if (m_frame == targetFrame)
    23192320        return true;
    23202321
    2321     // The navigation change is safe if the active frame is:
    2322     //   - in the same security domain (satisfies same-origin policy)
    2323     //   - the opener frame
    2324     //   - an ancestor or a descendant in frame tree hierarchy
    2325 
    2326     // Same security domain case.
     2322    if (!targetFrame->tree()->parent())
     2323        return true;
     2324
    23272325    Document* activeDocument = m_frame->document();
    23282326    ASSERT(activeDocument);
    2329     Document* targetDocument = targetFrame->document();
    2330     if (!targetDocument)
    2331         return true;
    23322327    const SecurityOrigin& activeSecurityOrigin = activeDocument->securityOrigin();
    2333     const SecurityOrigin& targetSecurityOrigin = targetDocument->securityOrigin();
    2334     if (activeSecurityOrigin.canAccess(targetSecurityOrigin))
    2335         return true;
    2336 
    2337     // Opener case.
    2338     if (m_frame == targetFrame->loader()->opener())
    2339         return true;
    2340 
    2341     // Ancestor or descendant case.
    2342     if (targetFrame->tree()->isDescendantOf(m_frame) || m_frame->tree()->isDescendantOf(targetFrame))
    2343         return true;
     2328    for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree()->parent()) {
     2329        Document* ancestorDocument = ancestorFrame->document();
     2330        if (!ancestorDocument)
     2331            return true;
     2332
     2333        const SecurityOrigin& ancestorSecurityOrigin = ancestorDocument->securityOrigin();
     2334        if (activeSecurityOrigin.canAccess(ancestorSecurityOrigin))
     2335            return true;
     2336    }
    23442337
    23452338    if (!targetFrame->settings()->privateBrowsingEnabled()) {
     2339        Document* targetDocument = targetFrame->document();
    23462340        // FIXME: this error message should contain more specifics of why the navigation change is not allowed.
    23472341        String message = String::format("Unsafe JavaScript attempt to initiate a navigation change for frame with URL %s from frame with URL %s.\n",
  • trunk/WebCore/page/FrameTree.cpp

    r28057 r28225  
    283283}
    284284
    285 }
     285Frame* FrameTree::top() const
     286{
     287    if (Page* page = m_thisFrame->page())
     288        return page->mainFrame();
     289
     290    Frame* frame = m_thisFrame;
     291    while (Frame* parent = frame->tree()->parent())
     292        frame = parent;
     293    return frame;
     294}
     295
     296} // namespace WebCore
  • trunk/WebCore/page/FrameTree.h

    r25754 r28225  
    6565        AtomicString uniqueChildName(const AtomicString& requestedName) const;
    6666
     67        Frame* top() const;
     68
    6769    private:
    6870        Frame* deepLastChild() const;
Note: See TracChangeset for help on using the changeset viewer.