10

我有一个提供纯 HTML 和 JS 文件的 nginx 服务器。

然后,js 代码调用各种 REST API 从 API 服务器获取/发布数据。

如果 nginx 收到对 /api/ 位置的请求,它会将请求转发到另一个处理所有 API 的服务器。这个 api 服务器是用 Ruby on Rails 构建的。

由于我所有的纯 HTML 页面都是由 nginx 直接提供的,因此在呈现它们时我不能有服务器端会话。

我可以做些什么来防止 CSRF 攻击?

4

3 回答 3

6

CSRF 令牌的目的是要求攻击者从您的域中读取一个值以便发送请求。

因此,您可以在 API 中有一个单独的端点,它只返回一个 CSRF 表单令牌。

由于同源策略,攻击者将无法读取令牌(与他们无法从 HTML 源读取令牌的原因相同),因此您将是安全的。
这样做的缺点是需要额外的 HTTP 请求。

此外,请确保响应不是有效的 Javascript,否则攻击者可以将其作为<script>标签运行并使用原型和属性技巧来读取值

于 2013-12-29T14:38:08.513 回答
3

由于您不能拥有服务器端会话,因此您需要一个不需要将令牌存储在服务器上的解决方案。相反,您需要做的是让您的 nginx 实现生成某种令牌,您将在对浏览器的响应中包含这些令牌。当攻击者代表另一个用户发送请求时,该值应出现在请求中未自动包含的位置(即应用程序生成的页面上的隐藏输入字段或元标记),并且还应存储在一个 cookie(显然会在 CSRF 攻击中自动发送)。当您的应用程序收到请求时,它可以验证这两个值是否相等。如果是这样,您可以将请求转发到 API。如果不是,您知道请求不是来自您的站点,您可以拒绝。

至少有两种方法可以做到这一点:

好: csrf_cookie: abc123 (cookie) csrf_param: abc123 (参数或标头)

更好:session_+_csrf_cookie:sessionid_val_--abc123 csrf_param:abc123(参数或标头)

第二种解决方案优于第一种的原因是第一种解决方案容易受到 cookie 强制的影响。第二个是安全的,因为如果 MITM 与您的会话 cookie 混淆,它无论如何都会使会话无效。使用第二种解决方案,您可以在代理到 API 之前简单地剥离令牌。

当然,所有这些都假设您使用的是 HTTPS。

于 2014-02-20T22:25:31.187 回答
1

安装 WAF(Web 应用程序防火墙)来检查 HTTP/HTTPS 流量,拒绝恶意请求,并且通常充当 Web 堆栈中的附加安全层。正确配置的 WAF 可以保护您的站点免受 SQLi、XSS、CSRF 和 DDoS 攻击,并提供暴力攻击缓解和零日威胁修补。
有一些可用于 nginx 的开源 WAF 选项。请参阅https://help.dreamhost.com/hc/en-us/articles/222784068-The-most-important-steps-to-take-to-make-an-nginx-server-more-secure

还有一个简单的 nginx 模块,它将引用者或源头与主机头进行比较。如果域名不匹配,则返回 HTTP 响应 403。见https://github.com/gartnera/nginx_csrf_prevent

于 2018-05-13T00:05:19.440 回答