使用跨域JavaScript调用来防止CSRF

时间:2011-04-01 19:32:24

标签: javascript json jsonp csrf

我想保护自己的网站免受cross-site request forgery的攻击。我正在尝试关注these recommendations,通过发送特定于会话的令牌以及所有需要保护的请求。

问题在于,我有一些请求旨在由第三方网站在不同的域上调用。他们中的大多数使用JSONP:他们使用<script>标记向我们的服务器发出请求,响应是调用其页面上的函数的JavaScript代码。

我的问题是,如何在这些请求中传递令牌?看起来第三方网站需要知道令牌。我可以提供另一个请求,将令牌作为JSON返回,但是不受信任的站点可以发出相同的请求,获取令牌,并使用它来伪造对我们服务器的请求。

有更好的方法吗?

3 个答案:

答案 0 :(得分:3)

XSRF令牌通常是您生成的域中的Cookie。你真的不想引入一种机制来允许其他网站设置它们。验证来自受信任方的邮件最好被视为签名验证问题。

您可以让每个合作伙伴网站生成并保留私人/公共signature密钥对。然后他们可以发给你他们的公钥。

然后他们可以给你发信息。

所以他们的请求看起来像是

 <script src="https://.../yourservice?partnerid=foobar&signedquerystring"></script>

然后您可以使用您通过密钥foobar查找的公钥签名检查已签名的查询字符串是否已正确签名。

您现在知道如果该请求具有您的XSRF令牌,或者使用与您建立关系的合作伙伴的私钥进行了正确签名,则您信任该请求。

这不会阻止可以观察登录用户查看合作伙伴网站的人重播请求,因此合作伙伴网站和您的脚本都应该通过安全通道(https)加载,就像你会使用多用途的XSRF代币。

答案 1 :(得分:0)

我正在使用的解决方案是在我正在创建的外部窗口小部件的UI中嵌入IFRAME。这里唯一的缺点是其他人可能会在点击劫持攻击中使用这个iframe。你可以在这里阅读:https://security.stackexchange.com/questions/13341/security-issues-using-iframes

答案 2 :(得分:0)

我有最简单的JSONP CSRF问题解决方案,添加“While(1);”或“for(,,);”或扔“F *** U”;在你的json响应数据的开始。

现在任何JSONP请求都以无限循环结束。因为您没有使用JSONP请求,所以您可以通过此代码修改响应

JSON.parse(this.responseText.slice("while(1);".length));