如何配置MediaWiki允许内联CSS使用本站PNG作为mask-image?
我正在搭建一个基于MediaWiki平台并搭配Semantic MediaWiki扩展的游戏Wiki,想要制作一个模板,能在特定概念名称前添加图标。这些图标是仅包含白色像素(从完全不透明到完全透明)的PNG图片,需要自动继承当前文本的颜色。
举个例子:Wiki中有一个名为“Heat”的页面,页面内通过{{#set: icon=File:UIT_Icon_Heat.png}}设置了对应图标(该PNG是已上传至Wiki的文件),我希望在任意页面使用{{ico|Heat}}这类调用后,图标能以与“Heat”文字相同的颜色显示在文字前方。
目前能在所有浏览器生效的实现方式,是将图片通过url()函数设置为CSS或SVG的mask-image,但出于安全限制,内联style=""声明中任何url()的使用都会导致整个声明被移除。MDN文档提到image()函数是CSS规范定义的替代方案,但目前无浏览器支持,无法解决问题。
当前临时方案是在仅管理员有权限编辑的Common.css页面中,为每个图标单独添加CSS类并指定url(),再由模板调用对应类。该方法虽能正常工作,但普通用户无法添加新图标,我希望实现让普通用户无需特殊权限也能添加新图标的效果。
请问是否可配置Wiki,允许内联使用url()函数但仅针对本站域名下的PNG文件,且不会引入插入恶意代码链接等安全漏洞?若不可行,是否有其他方法能让普通用户无需特殊权限即可将PNG图片设为CSS mask-image?
一、关于内联url()的权限配置
MediaWiki的安全机制(核心是$wgAllowInlineStyle配置和内容安全策略CSP)默认会严格过滤内联style中的url()。即使限制为本站域名的PNG,仍存在安全风险:比如若允许上传SVG文件,恶意用户可构造带脚本的SVG并通过url()引用触发漏洞;或利用本站资源的特殊路径触发其他安全问题。因此没有官方支持的方式单独放开本站PNG的内联url(),强行修改核心代码或扩展会破坏安全模型,不建议操作。
二、普通用户可操作的替代方案
1. 利用Semantic MediaWiki属性+内联SVG实现
由于图标是白色透明PNG,可以通过SMW获取图标路径后,动态生成带mask的内联SVG,自动继承文本颜色:
- 模板
ico的核心逻辑:- 通过
{{#show: {{{1}}}|?icon}}获取目标页面设置的图标文件 - 将文件路径转换为Wiki的公开访问URL(如
/w/images/xxx/UIT_Icon_Heat.png) - 生成内联SVG,用
<mask>引用该PNG,再用填充currentColor的矩形应用mask:
- 通过
<span style="display: inline-block; vertical-align: middle; margin-right: 4px;"> <svg width="16" height="16" viewBox="0 0 16 16"> <mask id="icon-mask-{{#uniq:}}"> <image href="{{{icon-url}}}" width="16" height="16" /> </mask> <rect width="100%" height="100%" fill="currentColor" mask="url(#icon-mask-{{#uniq:}})" /> </svg> </span>[[{{{1}}}]]
其中{{#uniq:}}用于生成唯一的mask ID,避免页面内多个图标冲突。
- 优势:普通用户只需上传PNG并设置
icon属性即可使用,无需修改CSS;SVG的href指向本站资源不会被过滤,currentColor自动继承文本颜色。
2. 借助TemplateStyles扩展实现
安装MediaWiki官方推荐的TemplateStyles扩展后,普通用户可在模板中嵌入经过安全过滤的自定义CSS,该扩展会验证url()指向的资源是否为本站合法文件:
- 模板
ico的核心逻辑:- 获取图标文件的公开访问URL
- 用
<templatestyles>标签嵌入动态生成的CSS,定义临时类的mask-image规则 - 为目标链接添加该临时类:
<templatestyles> .icon-temp-{{#uniq:}} { mask-image: url("{{{icon-url}}}"); -webkit-mask-image: url("{{{icon-url}}}"); mask-size: 16px 16px; -webkit-mask-size: 16px 16px; mask-position: left center; -webkit-mask-position: left center; mask-repeat: no-repeat; -webkit-mask-repeat: no-repeat; padding-left: 20px; background-color: currentColor; display: inline-block; } </templatestyles> <span class="icon-temp-{{#uniq:}}">[[{{{1}}}]]</span>
- 优势:
TemplateStyles会自动过滤非法资源,普通用户可通过模板动态生成对应图标的CSS规则,无需管理员权限。
3. 辅助脚本+审核机制(无扩展方案)
若不想安装扩展,可编写Lua模块(通过#invoke调用),让普通用户提交图标文件后,脚本自动将图标URL添加到一个专门的CSS页面(如MediaWiki:Custom-icons.css),再由管理员批量审核后生效。这种方案需要管理员配置脚本权限,操作相对繁琐,但适合无法安装扩展的场景。
内容的提问来源于stack exchange,提问作者Lawton

