什么是 SOME?
同源方法执行漏洞(Same Origin Method Execution)是一种攻击者可以控制页面 Javascript 执行回调函数的漏洞。乍看之下,这种漏洞好像没什么危害,除非攻击者可以代替用户执行页面上敏感的 Javascript 函数。例如,网站上存在一个 deleteAccount
的 Javascript 函数,而攻击者可以代替用户调用这个函数。
另外,攻击者还可以利用这种漏洞来操作 DOM。例如,假设页面上存在一个按钮,攻击者就可以通过执行如下 Javascript 来点击到这个按钮:
document.firstElement.nextSiblingElement.nextSiblingElement.click
如何利用?
网站交互时有时会需要用户要提供一个参数用作要被执行函数的函数名,然后网站在执行对应的 Javascript 函数。JSONP(JSON with Padding)就是允许用户传递一个回调参数给服务端,然后服务端返回数据时会将这个回调参数作为函数名来包裹住 JSON 数据。一个简单的 PHP 示例如下:
https://example.com/main <?php echo ‘<script src="https://example.com/jsonp?callback=’ . $_GET[“userParam”] .‘ “>’; ?>
在上面的代码段中,用户的输入被直接注入到了 script 标签中,JSONP( https://example.com/jsonp
)会返回类似如下的内容:
userParam({ jsonp : data }) // userParam 就是用户之前通过 GET 方法提交的内容
当然,上面的代码段还存在其他很多问题,例如还可以导致 XSS 等等,因为用户提交的参数没有进过过滤就直接拼接到了 Javascript 中进行执行。
在常见的生产环境下,理想的方法是定义一个基于白名单的安全回调函数,只接受来自用户输入中特定的字符。这种方法通常的确可以抵御 XSS 和其他基于 JSONP 的 Rosetta Flash 攻击,但依旧无法阻止 SOME 攻击。事实上如前文所说,攻击者还可能通过使用内建方法来操纵 DOM,如使用 firstElementChild
, lastElementChild
和 nextElementSibling
,这样攻击者就可以通过使用 Javascript 方法访问到页面上任意的元素。
深入利用
如果攻击者发现一个网站应用存在 SOME 漏洞,那他们绝不会仅仅满足于浏览网页上的各个元素,相反,通过使用 Javascript 内建的 window.opener
方法可以打开同源网站的其他页面。利用这种方法可以大大的扩展攻击面,但缺点也很明显就是需要打开多个页面。
使用 window.opener
由于我们需要打开多个页面来进行攻击,所以用户必须先登录到攻击者控制的页面上,具体攻击流程如下:
- 用户登录到攻击者的控制的页面(后续称为Window 1);
- 从 Window 1中启动一个新窗口(后续称为Window 2);
- Window 2 是由 Window 1 通过
window.opener
打开的与攻击者控制页面同源的页面; - Window 1 重定向到包含按钮或者其他攻击者想执行 Javascript 方法的目标页面;
- Window 2 使用
window.opener
方法打开与 Window 1 目标页面同源的存在SOME漏洞的页面; - Window 2 以
window.opener.functionToExecute
作为回调进行执行; - 此时,函数会在 Window 1 中被执行。
这样,攻击者就完成了对同源网站的攻击了,具体可视化的流程图如下:
攻击步骤
上一节提到的攻击可以被页面上额外的确认弹窗提示阻止,尽管如此,攻击者依旧可以通过以下流程产生额外的窗口来绕过检查:
- 用户登录到攻击者的控制的页面(后续称为Window 1);
- 从 Window 1中启动一个新窗口(后续称为Window 2);
- 从 Window 1中启动一个新窗口(后续称为Window 3);
- Window 2 和 Window 3 是由 Window 1 通过
window.opener
打开的与攻击者控制页面同源的页面; - Window 1 重定向到包含按钮或者其他攻击者想执行 Javascript 方法的页面;
- Window 2 和 Window 3 使用
window.opener
方法打开与 Window 1 目标页面同源的存在SOME漏洞的页面; - Window 2 以
window.opener.buttonToClick.click
作为回调进行执行,此时 Window 1 页面上的按钮会被点击且同时弹出额外的确认弹窗; - Window 3 以
window.opener.buttonToConfirm.click
作为回调进行执行,以此来点击 Window 1 页面上确认弹窗的确认按钮; - Window 1 上的两个确认按钮均被点击,攻击完成。
SOMEtime - 一个 BurpSuite 插件
SOMEtime 是一个 BurpSuite 开源的被动式扫描插件,通过监听 HTTP 请求与响应来判断目标是否存在 SOME 漏洞。至于具体如果安装与使用这个插件,请参阅其官方 Github 页面: https://github.com/linkedin/sometime 。
缓解 SOME 攻击的建议
- 网站应用应尽量使用静态定义的回调值;
- 如果你需要同时支持多个回调端点,最好的办法就是在服务端使用白名单控制回调值,只有指定的回调值才会被执行。
- 通常来说,JSONP 是一种可以用来绕过同源策略有争议的技术,如果不是必须要使用,建议使用 window.postMessage 这个更安全的方法来代替完成跨域请求执行。
原文: linkedin
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。