无需 JavaScript 即可安全地将不受信任的输入分配给 CSS 自定义属性:指南
P粉356361722
P粉356361722 2023-09-06 22:32:52
[CSS3讨论组]

假设我有一个字符串键和字符串值的对象,我想将它们作为 CSS 自定义属性写入服务器生成的一些 HTML 中。我怎样才能安全地做到这一点?

我所说的安全是指

  • 如果可能的话,自定义属性声明不应导致 CSS 语法错误,从而阻止浏览器正确解析其他样式声明或 HTML 文档的部分。如果由于某种原因这是不可能的,则应省略键值对。
  • 更重要的是,这样应该不可能进行跨站点脚本编写。

为了简单起见,我将限制键仅允许 [a-zA-Z0-9_-] 类中的字符。

通过阅读 CSS 规范和一些个人测试,我认为通过以下步骤获取值可以取得很大的进展:

  • 查找字符串
  • 确保每个引号后面都有另一个相同类型(“或')的(未转义的)引号。如果不是这种情况,请丢弃此键/值对。
  • 确保字符串外部的每个左大括号 {([字符串外部的 都有一个匹配的右大括号。如果没有,则丢弃此键值对。
  • 使用 \3C 转义 < 的所有实例,以及使用 3E 转义 > 的所有实例。
  • 使用 \3B; 的所有实例进行转义。

我根据这个 CSS 语法规范想出了上述步骤

对于上下文,这些属性可以由我们在其他地方插入的用户自定义样式使用,但同一对象也用作模板中的模板数据,因此它可能包含旨在作为内容的字符串和预期的字符串的混合作为 CSS 变量。我觉得上面的算法取得了很好的平衡,既非常简单,又不会冒丢弃太多可能在 CSS 中有用的键值对的风险(即使考虑到未来对 CSS 的添加,但我想确保我没有遗漏什么。


这里有一些 JS 代码,展示了我想要实现的目标。 obj 是有问题的对象,而 preprocessPairs 是一个函数,它接受该对象并对其进行预处理,删除/重新格式化值,如上述步骤所述。

function generateThemePropertiesTag(obj) {
  obj = preprocessPairs(obj);
  return ``
}

所以当给定一个这样的对象时

{
  "color": "#D3A",
  "title": "The quick brown fox"
}

我希望 CSS 看起来像这样:

:root {
--theme-color: #D3A;
--theme-title: The quick brown fox;
}

虽然 --theme-title 在 CSS 中使用时是一个非常无用的自定义变量,但它实际上并没有破坏样式表,因为 CSS 会忽略它不理解的属性。

P粉356361722
P粉356361722

全部回复(0)
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号