前端安全审计中如何评估CSS注入风险?

诸葛莉霞 阅读 72

最近在做项目安全自查,发现用户能自定义主题色,但担心CSS注入问题。我用了类似下面的写法,这样安全吗?

.user-theme {
  --primary-color: ${userInput};
  background-color: var(--primary-color);
}

虽然没直接用 innerHTML,但变量插到 CSS 里会不会被绕过?有没有更安全的做法?

我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
シ树泽
シ树泽 Lv1
CSS变量本身比较安全,因为现代浏览器会对CSS变量值做解析,不能直接执行JS代码。但你这写法还是可能有问题的,比如用户输入类似这种:
red; --hack: url('javascript:alert(1)');


更安全的做法是加个正则校验,只允许16进制或标准颜色名。代码给你:

function sanitizeColor(input) {
// 匹配 #rgb #rrggbb 或标准颜色名
const colorRegex = /^#([0-9a-f]{3}){1,2}$|^[a-z]+$/i;
return colorRegex.test(input) ? input : '#000';
}

// 使用
const safeColor = sanitizeColor(userInput);
document.documentElement.style.setProperty('--primary-color', safeColor);


另外建议用style.setProperty而不是字符串拼接,双重保险。真要特别严谨的话,可以再用CSS.supports()验证下。
点赞 1
2026-03-05 22:09
诸葛篷璐
你这种写法确实存在风险。CSS注入不只是innerHTML的问题,关键是用户输入能不能逃逸出CSS语法。比如用户输入 red); font-size: 100px; /* 这种,最终生成的CSS就崩了。

建议这么处理:

1. 如果只是颜色值,直接用正则校验格式:
const isValidColor = /^#[0-9a-f]{3,6}$|^rgb(a)?([sd%,]+)$/i.test(userInput);


2. 更严格点可以用CSS.supports()验证(注意浏览器兼容性):
if(CSS.supports('color', userInput)) {
// 安全的
}


3. 实在不放心就直接用白名单,只允许预定义的几种颜色值。

顺便吐槽下,前端安全最容易被忽视的就是这种小细节,之前我们项目就被人用 url(javascript:alert(1)) 这种骚操作绕过过。所以涉及用户输入的地方,一定得把校验做死。
点赞 2
2026-03-05 15:04