csrf攻击防范的核心在于验证请求来源合法性。解决方案包括:1.referer头检查,通过nginx配置限制请求来源,但存在被伪造风险;2.origin头检查,相比referer更可靠,但浏览器兼容性需注意;3.双重提交cookie,前端生成token并同时置于cookie和请求参数中,nginx初步验证,安全性更高但实现复杂;4.自定义请求头验证,适用于api接口,避免跨域问题。选择方案时应权衡安全性和实现成本,结合多种方法提升防护效果。此外,nginx层防护不能替代后端验证,仍需后端进一步确认token有效性。其他手段如同步令牌模式、samesite cookie及用户行为验证也应纳入整体防御策略。

CSRF攻击防范的核心在于验证请求的来源是否合法。在Nginx层进行防护,可以有效拦截恶意请求,减轻后端服务器的压力。
解决方案:
Referer Header 检查:  Nginx可以配置检查Referer请求头。如果Referer头不存在或不在白名单内,则拒绝请求。  这种方法简单直接,但Referer头可以被篡改,因此并非万无一失。
server {
    listen 80;
    server_name example.com;
    location / {
        if ($http_referer !~ "^https?://(www\.)?example\.com") {
            return 403;
        }
        proxy_pass http://backend;
    }
}Origin Header 检查: Origin头比Referer头更可靠,因为它不能被浏览器在跨域请求中修改。  Nginx可以配置检查Origin头,并只允许来自特定域的请求。 但要注意,Origin头并非所有浏览器都支持。
server {
    listen 80;
    server_name example.com;
    location / {
        if ($http_origin !~ "^https?://(www\.)?example\.com") {
            return 403;
        }
        proxy_pass http://backend;
    }
}双重提交 Cookie (Double Submit Cookie): 这种方法需要在前端生成一个随机的token,将其同时存储在cookie中和一个请求参数中。 Nginx可以配置验证这两个token是否一致。 虽然增加了复杂度,但安全性更高。
前端生成token并设置cookie: (假设使用JavaScript)
function setCookie(name,value,days) {
    var expires = "";
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days*24*60*60*1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "")  + expires + "; path=/";
}
function generateToken() {
    // 简单示例,实际应用中应使用更安全的随机数生成方法
    return Math.random().toString(36).substring(2);
}
const csrfToken = generateToken();
setCookie('csrf_token', csrfToken, 7); // 设置cookie有效期为7天
// 将csrfToken添加到表单或AJAX请求参数中
// 例如: <input type="hidden" name="csrf_token" value="${csrfToken}">Nginx配置: (这里假设后端服务会验证这个token,Nginx只做初步的检查)
server {
    listen 80;
    server_name example.com;
    location / {
        # 检查是否存在cookie和请求参数中的csrf_token
        if ($http_cookie !~* "csrf_token=([^;]+)") {
            return 403;
        }
        if ($request_method = POST) {
          if ($arg_csrf_token = "") {
            return 403;
          }
          # 这里无法直接比较cookie和参数的值,只能简单判断存在性
          # 实际的token验证需要在后端进行
        }
        proxy_pass http://backend;
    }
}自定义请求头验证: 类似于双重提交Cookie,但将Token放在自定义的请求头中。 这种方式避免了Cookie的跨域问题,更适用于API接口。
前端设置自定义请求头:
  //  假设已经通过某种方式获取了CSRF token (例如从cookie中读取)
  const csrfToken = getCookie('csrf_token'); // 需要自己实现getCookie函数
  fetch('/api/resource', {
      method: 'POST',
      headers: {
          'Content-Type': 'application/json',
          'X-CSRF-Token': csrfToken // 自定义请求头
      },
      body: JSON.stringify({ data: 'your data' })
  })
  .then(response => response.json())
  .then(data => console.log(data));Nginx配置:
  server {
      listen 80;
      server_name example.com;
      location /api/ {
          if ($http_x_csrf_token = "") {
              return 403;
          }
          proxy_pass http://backend;
      }
  }选择哪种方案取决于你的应用场景和安全需求。  Referer和Origin检查简单易用,但安全性较低。  双重提交Cookie和自定义请求头验证安全性更高,但实现起来更复杂。  可以根据实际情况选择组合使用多种方案。  关键在于理解每种方案的优缺点,并根据自身情况进行权衡。
Nginx层主要负责请求的初步过滤,它无法完全替代后端服务器的CSRF防护。 例如,Nginx无法验证双重提交Cookie中的token是否与用户的session关联。 因此,即使在Nginx层进行了防护,后端服务器仍然需要进行更严格的验证。 Nginx主要起一个前置过滤的作用,减轻后端压力,提高整体安全性。
除了Nginx层防护,还有以下CSRF防护手段:
SameSite属性可以控制Cookie是否随跨站请求发送。 设置SameSite=Strict可以完全阻止Cookie在跨站请求中发送,从而有效防止CSRF攻击。  但要注意,SameSite=Strict可能会影响某些正常的跨站请求,需要谨慎使用。  SameSite=Lax 则允许部分跨站请求(例如GET请求)携带Cookie。这些方法通常需要在后端代码中实现。 结合Nginx层的防护,可以构建更强大的CSRF防御体系。
以上就是跨站请求伪造(CSRF)在 Nginx 层的防护方案的详细内容,更多请关注php中文网其它相关文章!
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号