如何在不使用JavaScript的情况下安全将不可信输入赋值给CSS自定义属性?
安全将字符串键值对象转为HTML中的CSS自定义属性
问题
我有一个由字符串键和字符串值组成的对象,希望将其作为CSS自定义属性写入服务器生成的HTML中,需要实现安全转换。
安全要求
- 尽可能避免自定义属性声明引发CSS语法错误,防止浏览器无法正确解析其他样式或HTML文档;若无法避免则舍弃对应键值对。
- 完全杜绝跨站脚本攻击(XSS)风险。
注:为简化处理,仅允许键包含[a-zA-Z0-9_-]范围内的字符。
拟采用的处理逻辑(针对值)
结合W3C CSS语法规范,我制定了以下值处理步骤:
- 检测字符串内容;
- 确保每个引号后都存在匹配的同类型未转义引号,否则舍弃该键值对;
- 确保字符串外的每个左括号
{([都有匹配的右括号,否则舍弃该键值对; - 将所有
<替换为\3C,>替换为\3E; - 将所有
;替换为\3B。
背景说明
这些属性可能用于用户自定义样式,同时该对象也会作为模板数据使用,因此可能混合了内容字符串与CSS变量字符串。我认为上述算法兼顾简洁性与实用性,不会过多舍弃可用的键值对,但希望确认是否存在遗漏。
实现代码示例
function generateThemePropertiesTag(obj) { obj = preprocessPairs(obj); return `<style> :root { ${Object.entries(obj).map(([key, value]) => { return `--theme-${key}: ${value};` }).join("\n")} } </style>` }
注:preprocessPairs为实现上述值处理步骤的预处理函数
输入输出示例
输入对象
{ "color": "#D3A", "title": "The quick brown fox" }
预期生成的CSS
:root { --theme-color: #D3A; --theme-title: The quick brown fox; }
尽管--theme-title作为CSS变量实用性较低,但不会破坏样式表,因为CSS会忽略无法识别的属性。
内容的提问来源于stack exchange,提问作者bigblind
相关产品推荐
相关产品推荐

