会。直接用style属性赋值可能触发XSS,因用户输入若含expression()、javascript:等可被旧版IE或特定解析器执行;现代浏览器虽限制部分语法,但攻击面仍在演化,且拼接时未过滤易导致属性闭合注入。

直接用 style 属性赋值会触发 XSS 吗?
会。当把用户输入拼接到 element.style.xxx 或 element.setAttribute('style', ...) 中时,如果内容含 expression()、javascript:、url(javascript:...) 等,旧版 IE 或某些解析器可能执行恶意逻辑;现代浏览器虽已禁用部分危险语法,但攻击面仍在演化。更常见的是,拼接过程绕过编码直接插入未过滤字符串,导致属性被闭合、后续注入生效。
- 不要写:
el.style.backgroundColor = userColor + '; ' + userImportant; - 也不要写:
el.setAttribute('style', 'color:' + userInput); - 即使只设单个属性,若
userInput是red; font-size:20px; background:url("javascript:alert(1)"),仍可能触发异常行为
安全设置内联 CSS 的正确方式有哪些?
核心原则:不拼接,不信任,不裸露字符串到样式上下文。优先走 DOM API 显式控制,其次对值做白名单校验或标准化。
- 对颜色、尺寸、数字类属性,用类型转换和范围校验:
parseInt(userSize, 10)、userColor.match(/^#([0-9A-F]{3}){1,2}$/i) - 对支持 CSS 函数的属性(如
transform),只允许预设关键词或数值参数,拒绝任意字符串 - 使用
CSS.supports()校验属性/值组合是否合法(例如CSS.supports('display', 'flex')),再赋值 - 若必须动态构造完整
style字符串,先用正则剥离所有非字母数字、连字符、括号、冒号、分号、空格以外的字符,再用CSSStyleSheet.insertRule注入临时规则(更可控)
为什么 innerHTML + style 标签也不安全?
因为 <style></style> 内容属于 CSS 上下文,但浏览器仍会解析其中的 @import url(...)、url()、attr() 等函数,而这些函数可嵌套 javascript: 或数据 URI 载入脚本。即使你过滤了 <script></script>,也拦不住:
-
<style>body{background:url("data:text/javascript,alert(1)")}</style> -
<style>*{font-family:src("javascript:alert(1)")}</style>
此外,document.write('<style>...</style>') 或 el.innerHTML = '<style>...</style>' 还会触发重排+重绘,性能差且易被混淆绕过。
立即学习“前端免费学习笔记(深入)”;
实际项目中容易被忽略的细节
最常被跳过的不是“怎么写”,而是“谁在写”。比如从 URL 参数读取主题色、从 localStorage 恢复上次样式配置、API 返回带样式的富文本片段——这些源头都默认不可信。
-
new URLSearchParams(location.search).get('theme')返回的值必须校验格式,不能直接进style -
localStorage.getItem('uiStyle')可能已被篡改,需 JSON.parse 后逐字段验证,而非直接Object.assign(el.style, ...) - 第三方富文本组件返回的 HTML 片段,即使用了
DOMPurify,其style属性仍需二次清理(DOMPurify.sanitize(html, { ADD_ATTR: ['style'] })不等于安全)
真正安全的内联 CSS 插入,从来不是靠“转义得够多”,而是靠“控制权不交给字符串”。


















