跨域Ajax表单提交 - 如何在允许任何域时避免使用XSS / CRSF?

时间:2014-01-29 19:04:30

标签: php ajax forms xss csrf

我正在为之工作的公司有一个表格,可以通过一行Javascript添加到任何网站。例如:

<script type="text/javascript" src="//ourserver.com/form.js?id=12345" />

在我们的服务器端,这由mod_rewrite获取并发送到生成表单代码(基于id)的PHP文件,并使用HTML代码执行document.write,并包含要处理的jQuery Ajax代码表格提交。

当然,浏览器和服务器并不是跨域Ajax的忠实粉丝,但我们通过添加标题来实现它:

header('access-control-allow-origin: *');

到我们服务器上的表单处理脚本(PHP)。但是,从我一直在阅读的内容来看,这个(以及一般的跨域发布)可以解决许多XSS / CSRF漏洞问题。

所以,我的问题是,我们应该如何设置javascript和PHP /服务器以帮助防止这些漏洞利用,同时仍允许将javascript放在任何域上?

我们不能将allow-origin标头限制为特定域,我尝试在生成表单时设置会话令牌,然后在提交表单时检查它,但由于表单的实现方式,会议没有结转。

1 个答案:

答案 0 :(得分:3)

当您使用Access-Control-Allow-Origin: *标头时,我假设提交表单的用户不使用cookie身份验证,因为通配符Access-Control-Allow-Origin无法使用凭证请求。

这意味着您不必担心CSRF攻击,因为该表单无法在其他用户的上下文中自动提交。

CSRF通常在用户登录网站时发生。例如www.foo.com然后他们访问其他网站(例如www.evil.com),而无需退出www.foo.com。假设www.evil.com在页面中包含图像请求。

e.g。

<img src="https://www.foo.com/DeleteAccount" />

由于用户已登录www.foo.com,因此将使用此请求发送身份验证Cookie,并删除用户的帐户。但是,由于您没有使用auth cookie,因此无法进行此类攻击。

此外,由于您没有从服务器返回任何敏感信息,因此允许Access-Control-Allow-Origin标头中的任何域都可以,只要它仅适用于AJAX POST的处理程序。如果您在AJAX JSON响应中返回任何错误消息,请确保它不包含有关您的服务器的任何机密数据。这是一个information leakage漏洞,与CSRFXSS分开。

XSS然后......根据您的描述,在您的情况下,XSS没有比普通网站更多的风险。第三方网站信任您的网站在其网域上下文中执行脚本,方法是在其网页上添加<script>标记,而不是相反。您只需要确保将任何输出正确编码到.js文件或JSON响应中。 JS编码是在这两种情况下都需要的转义(不是HTML编码)。请参阅Rule #3中的OWASP XSS Prevention Cheat Sheet

您的会话方法不起作用的原因是您没有在回复中包含Access-Control-Allow-Credentials: true,因此不会通过POST发送Cookie。如果您想使用此功能,则必须更改Access-Control-Allow-Origin标头以反映请求中的Origin标头(因为带有凭证请求的*通配符不允许)。