为什么设置CORS的’Access-Control-Allow-Origin’为’*’时存在安全风险?

佳怡酱~ 阅读 24

我在开发一个前后端分离的项目,前端用fetch调用另一个域名的API时,后端设置了Access-Control-Allow-Origin: *,虽然能正常跨域请求了,但看到资料说这样有安全风险。试过改成分具体域名后问题依旧存在,但不确定具体哪里出错。

比如用户登录接口返回的cookie被其他站点盗用了,后来查日志发现攻击者用了我的通配符配置发起请求。现在搞不清楚:为什么设置成*就会让攻击者能读取响应数据?如果必须动态设置origin,应该如何正确实现呢?

尝试过在Express中用中间件动态判断来源:


app.use((req, res, next) => {
  const allowedOrigins = ['https://safe.site.com', 'https://staging.site.com'];
  const origin = req.headers.origin;
  if(allowedOrigins.includes(origin)) {
    res.header('Access-Control-Allow-Origin', origin);
    res.header('Vary', 'Origin');
  }
  next();
});

但测试时发现预检请求OPTIONS返回404,是不是还有其他配置没考虑到?

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
技术晓莉
设置 Access-Control-Allow-Origin* 的确是个常见但危险的做法,原因很简单:它允许任何站点跨域访问你的资源。攻击者可以利用这个配置发起跨站请求伪造(CSRF)攻击。比如你提到的用户登录接口返回的cookie被其他站点盗用的问题,就是因为通配符让恶意站点也能合法地发送请求并获取响应。

具体来说,当 Access-Control-Allow-Origin 设置为 * 时,浏览器会认为你的服务允许所有来源的跨域请求。如果攻击者诱导用户访问了他们的站点,同时你的后端又没有对敏感请求做额外防护,那么攻击者就可以利用用户的已登录状态发起恶意请求,甚至读取返回的数据。

至于你提到的动态设置origin的实现,思路是对的,但还有几个点需要注意:

1. 预检请求OPTIONS返回404的问题,通常是因为你的路由处理逻辑没有正确匹配到OPTIONS请求。你需要确保中间件在所有路由之前执行,并且对OPTIONS请求做出明确响应。

2. 动态判断来源时,除了检查 req.headers.origin,还要确保只允许可信的域名。你的代码里已经有一个白名单数组,这很好,但别忘了处理一些边界情况,比如大小写不一致或者恶意构造的子域名。

3. 别忘了设置 Access-Control-Allow-Credentialstrue,如果你的API需要支持带凭证的请求(比如cookies、HTTP认证等)。不过一旦设置了这个头,就不能再把 Access-Control-Allow-Origin 设置为 *,否则浏览器会直接拒绝。

下面是一个改进后的Express中间件示例:

app.use((req, res, next) => {
const allowedOrigins = ['https://safe.site.com', 'https://staging.site.com'];
const origin = req.headers.origin;

// 检查是否是允许的来源
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Vary', 'Origin');

// 如果需要支持带凭证的请求
res.setHeader('Access-Control-Allow-Credentials', 'true');
}

// 处理预检请求
if (req.method === 'OPTIONS') {
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
return res.status(204).end(); // 预检请求直接返回204
}

next();
});


另外,建议你在生产环境中启用更严格的防护机制,比如结合CSRF token验证和Referer校验。这样即使CORS配置有问题,也能多一层保护。最后提醒一句,调试这种问题的时候,打开浏览器开发者工具的网络面板,仔细观察请求和响应头,能帮你更快定位问题。
点赞
2026-02-17 11:14