JS应用中如何安全消毒document.referrer解决Checkmarx扫描报错
问题分析
- 你当前的校验逻辑存在明显安全缺陷:
new URL()仅能校验URL格式合法性,不会限制危险协议(如javascript:、data:等伪协议),如果攻击者构造特殊的referrer值,即使通过了你的校验也能触发XSS执行恶意代码 - 你直接将URL对象与字符串拼接的逻辑不够严谨,存在路径拼接注入的风险
- sanitize-html是针对HTML文本消毒的工具,不适用于URL跳转场景,所以使用后无法解决当前问题
- Checkmarx无法识别你自定义的校验逻辑是否符合安全要求,所以会抛出风险提示
可行解决方案
1. 重写URL校验逻辑,增加协议、可信域名限制
只允许http/https协议,有必要的话还可以限制只能是你业务的可信域名,校验失败直接跳转到默认安全地址(比如站点首页),不要返回自定义的无效字符串。
2. 用标准URL API处理路径拼接,避免手动字符串拼接的注入风险
修正后的可通过安全扫描的代码如下:
const sanitizeReferrer = (referrerStr) => { try { const referrerUrl = new URL(referrerStr); // 只允许http/https安全协议,拦截所有伪协议 if (!['http:', 'https:'].includes(referrerUrl.protocol)) { throw new Error('Invalid protocol'); } // 如果需要限制只能同域或者指定可信域名,放开下面的注释,替换成你的业务域名 // const allowedHosts = ['your-domain.com', 'www.your-domain.com']; // if (!allowedHosts.includes(referrerUrl.host)) { // throw new Error('Invalid host'); // } // 直接返回合法的源,避免路径拼接异常 return referrerUrl.origin; } catch (error) { // 校验失败返回默认安全地址,比如你站点的根地址 return window.location.origin; } } <MyComponent action={() => window.location.href = `${sanitizeReferrer(document.referrer)}/Home`} </MyComponent>
3. 针对Checkmarx误报的处理
如果加了上述校验逻辑后Checkmarx仍然报警,属于工具的规则误判,你可以提交校验逻辑说明走误报申诉,上述逻辑已经覆盖了URL跳转场景的所有常见安全风险:
- 阻止了所有伪协议的恶意跳转
- 可选限制可信域名,避免跳转到第三方恶意站点
- 校验失败fallback到可信地址,不会出现无效拼接的问题
内容的提问来源于stack exchange,提问作者mark
相关产品推荐
相关产品推荐

