矢量图标能带脚本,上传图片时净化该挡掉哪些内容
矢量图标能带脚本,说的是文件类型本身的能力,不是某个漏洞。它扩展名为 .svg,常被当作图标随图片一起上传,但它是标记语言写成的文档:官方文档对脚本元素的描述直接写明「allows you to add scripts to an SVG document」,即脚本可以成为文档的一部分,外部脚本还能通过异步或延迟属性决定执行时机。所以「上传的是图片」这个前提,在这个格式上并不成立。
风险随打开方式变化
同一份文件,两种打开方式后果不同。作为 的引用来源加载时,脚本一般不被执行,风险较低;但用户或链接直接在浏览器标签里打开它,它就成了一份可执行文档,脚本在文件被加载的那个源下运行。如果它挂在站点自己的域与路径下,运行环境就是站点的上下文,Cookie 与登录态都在范围内。
因此不能只按扩展名与 MIME 判定安全。判定要看内容,处理要落在入库前。
净化要挡掉哪些内容
| 类别 | 具体对象 | 处理建议 |
|---|---|---|
| 脚本类 | 脚本元素、内联事件属性(如 onclick 一类) | 直接移除 |
| 外部引用 | 嵌入外部文档的引用元素、指向远程的地址 | 移除或改写为站内资源 |
| 跳转包装 | 可点击的链接包装元素 | 视业务需要保留,保留时限定站内地址 |
| 变形写法 | 实体编码、注释拼接、大小写混排 | 先归一化再判断 |
| 体积类 | 压缩变体的解压体积、嵌套层级 | 限制解压后大小与层级 |
| 标识类 | 文档内重复的元素标识 | 重命名或去重,避免与页面自身冲突 |
压缩变体的问题常被忽略:体积看着很小的压缩包,解压后可能是数量级更大的内容,还会在解析阶段消耗远超预期的资源。PbootCMS 在 V3.2.22 记录上传类型扩充时,同时写明「SVG 强制净化并限制 SVGZ 解压」,两件事放在一起处理是常见的做法。
黑名单与白名单怎么选
黑名单是「列出要删的」,白名单是「列出能留的」。黑名单省力,能保住原有展示效果,但覆盖面取决于列表是否跟得上新写法;白名单安全边界清晰,代价是可能把不认识的合法元素一并删掉,导致图标显示不全。
实践上两者常合用:先按白名单保留绘图与结构所需的元素,再用黑名单显式清除脚本、事件属性与外部引用,并在净化后重新序列化输出,避免原样透传。
站内处理落在哪一段
上传净化处理的是文件内容层,与站内的内容审核不是一件事。AnQiCMS 的内容安全设置包含敏感词过滤、关键词替换与内容审核,这些针对正文文本;文件层要看的是上传校验、类型限制与净化规则。自定义内容模型里如果把附件字段只当字符串存起来,净化就没有生效位置,字段定义要与实际处理链路对齐。
常见问题
只允许位图不就行了? 位图也有历史上的解析型问题,且矢量格式在图标场景确实更省。真要收紧可以按字段限制类型,但业务需要图标上传时,净化比禁止更可维护。
净化之后还要求存储隔离吗? 建议。文件按对象存储或独立目录存放,访问路径不接受脚本执行,能降低净化遗漏带来的后果。
远程抓图会带进同类内容吗? 会。远程抓取与后台上传走的是同一份格式判断,任一处放行都要同步净化,否则抓取通道成为旁路。