You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在CORS策略中使用indexOf做域名校验是否存在安全风险?

CORS白名单校验安全问题解答

现有方案的安全性评估

你提到的示例代码本身不存在http://example1.com.evil.com这类域名绕过的风险:

  • 代码中的whitelist.indexOf(origin)是在白名单数组中匹配完整的origin字符串,浏览器发起跨域请求时自动携带的origin头是包含协议、域名、端口的完整地址,恶意构造的http://example1.com.evil.com和白名单内的http://example1.com是完全不同的字符串,匹配会直接失败,不会被放行。

只有当匹配逻辑被错误写为「在origin字符串中查找是否包含白名单子串」时,才会出现你担心的绕过问题,这类错误写法示例如下:

// 错误写法,存在恶意域名绕过风险
var corsOptions = {
  origin: function (origin, callback) {
    // 错误点:判断origin是否包含白名单子串,而非完全匹配
    if (whitelist.some(allowedOrigin => origin.indexOf(allowedOrigin) !== -1)) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  }
}

更严谨的优化方案

如果你的业务只需要放行固定的完整origin,直接使用cors包内置的数组匹配能力即可,不需要自定义origin校验函数,避免手写逻辑出错:

const whitelist = ['http://example1.com', 'http://example2.com']
const corsOptions = {
  origin: whitelist // 直接传数组,cors包内部会自动做安全的完全匹配
}

如果需要支持子域名通配(比如允许*.example1.com的所有子域名),推荐通过URL对象解析域名后再做校验,不要直接做字符串模糊匹配:

const rootDomainWhitelist = new Set(['example1.com', 'example2.com'])
const corsOptions = {
  origin: function (origin, callback) {
    // 可根据业务需求决定是否放行无origin的同站请求
    if (!origin) return callback(new Error('Not allowed by CORS'))
    try {
      const requestHost = new URL(origin).hostname
      const isAllowed = rootDomainWhitelist.has(requestHost) 
        || Array.from(rootDomainWhitelist).some(domain => requestHost.endsWith(`.${domain}`))
      callback(null, isAllowed)
    } catch (err) {
      // 非法origin直接拦截
      callback(new Error('Not allowed by CORS'))
    }
  }
}

注意:如果用正则做自定义匹配,必须加开头和结尾锚点,例如匹配http://example1.com的正则应写为/^http:\/\/example1\.com$/,避免子串匹配漏洞。

内容的提问来源于stack exchange,提问作者Christopher Waugh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 04:30:00