SPIP 的一个漏洞:你以为过滤了,其实没过滤干净

SPIP 的一个漏洞:你以为过滤了,其实没过滤干净

SPIP 是个老牌 CMS,法国那边用得很多。它后台有个"安全屏"(security screen),专门拦危险输入------PHP 标签、系统命令、各种注入 payload,理论上到了这一层全给你挡回去。

但 CVE-2026-8429 让这个安全屏形同虚设。

怎么回事?一句话:

安全屏确实在干活,但攻击者找到了一条路径------构造的 payload 在到达"真正执行代码的地方"之前,经过了某个处理环节,这个环节把 payload 变形了。变形之后,代码执行点拿到的东西已经不是安全屏当初检查的那个了。


这就很像前端里一个经典问题:你写了个 XSS 过滤器,把 <script>onerror 全拦了。但攻击者传了段 Base64 编码的字符串------过滤器没认出来,放行了。然后下游某个渲染逻辑做了一次 atob(),解码出来的就是 <script>alert(1)</script>

过滤器和执行器之间多了一步"还原"操作,安全的假象就是这么来的。

js 复制代码
// 你以为过滤了
const input = atob(userInput); // 下游解码
const safe = sanitize(input);  // 过滤
render(safe);                  // 渲染

// 但实际可能是
const safe = sanitize(userInput); // 过滤的是编码版本------看起来无害
const decoded = atob(safe);       // 解码
render(decoded);                  // 渲染------恶意代码出现了

SPIP 这次的问题本质一样:安全屏检查的是 A,代码执行点拿到的是 B。A 和 B 长得不一样。


具体来说,SPIP 后台有个处理流程:

text 复制代码
用户输入 → 安全屏检查 → 通过 → 进入模板引擎/代码执行上下文

正常情况下,安全屏会抓出 <?phpsystem()eval() 这些危险模式。

但攻击者发现,某些输入经过 SPIP 内部的处理函数后,字符会被转义、拼接或重组。你在输入框里写的东西,安全屏看到的是一种形态,到了代码执行点因为经过了中间处理,变成了另一种形态------而变完之后恰好形成了可执行的 PHP 代码。

写成伪代码大概这种感觉:

js 复制代码
// 安全屏的逻辑(简化的等价版本)
function securityScreen(input) {
  if (input.includes('<?php')) throw new Error('blocked');
  if (input.includes('system')) throw new Error('blocked');
  return input; // 放行
}

// 下游的处理逻辑
function preprocess(input) {
  // 某种字符串处理,比如拼接模板标签、转义反转等
  return '<?php ' + input + ' ?>'; // 注意这里------它帮你拼上了 PHP 标签
}

// 事故的发生:
const userInput = 'system("id");';           // 不含 <?php,安全屏放行
const processed = preprocess(userInput);     // 变成了 '<?php system("id"); ?>'
eval(processed);                             // 代码执行

当然实际漏洞比这个绕------牵涉到 SPIP 的模板语法、过滤器绕过技巧、特定的 HTTP 参数组合。但核心问题就是:安全屏和执行点之间信息不对称。


这个漏洞危险在哪?

你需要一个后台账号。但 SPIP 的后台账号门槛不高------很多站点开放注册,或者用了弱密码。一旦进了后台,这个漏洞就能让你从"只能编辑文章"变成"服务器完全控制"。

而且你干了什么很难被发现。安全屏日志显示"检查通过",Web 日志显示正常的 POST 请求,Payload 在传输过程中看起来也不像传统 webshell。只有真正执行了才会暴露------那时候已经晚了。


怎么修?

原则就一句:安全屏检查的是啥,执行点就拿啥。中间别动。

SPIP 4.4.14 的修复思路是重构过滤逻辑,让安全屏覆盖输入的所有可能形态------包括被内部函数处理之后的状态。说白了你不管怎么变形,变形之前和变形之后我都检查一遍。

应用层如果暂时升不了级,几个缓解措施:

  • 后台加 IP 白名单或 MFA,先把攻击面缩到最小
  • Web 服务用最小权限跑(www-data,不要 root
  • 监控后台的异常请求------尤其是带编码内容、非典型参数的 POST

本地复现

需要搭建 SPIP < 4.4.14 环境(Docker 或本地 PHP + MySQL)。核心步骤:

  1. 用低权限账号登录 /ecrire/
  2. 在受影响的功能点(模板编辑、特定表单)提交 payload
  3. 触发渲染,观察命令是否执行

概念验证 payload(实际需根据版本调整触发路径):

text 复制代码
提交内容包含绕过安全屏的 PHP 片段,如经过编码或利用模板语法的:
[(#EVAL{system('id')})]

注意:具体触发点和 payload 格式因版本而异,以上仅为概念演示。实际复现需参考 VulnCheck 或 SentinelOne 的详细分析调整。


影响版本 :SPIP < 4.4.14 | 修复版本:4.4.14+

前提 :需低权限后台认证 | 参考:SentinelOne 分析 / SPIP 官方安全更新 / VulnCheck Advisory

相关推荐
এ慕ོ冬℘゜3 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
hoLzwEge3 小时前
拯救低效调试!code-inspector-plugin 让代码定位如虎添翼
前端·前端框架·node.js
J船长3 小时前
烂笔头扫盲:LLM Eval 入门:从「感觉挺好」到「数据说话」的工程化落地
前端
skiyee3 小时前
被多个 UView 系 UI 库 “抄” 的 @uni-ku/root 究竟怎么实现?
前端
鱼毓屿御3 小时前
从「只会聊」到「边想边做」的跃迁
前端·学习·react.js
sugar__salt4 小时前
Vue3 表单双向绑定与响应式核心 API 技术详解
前端·javascript·vue.js
郝亚军4 小时前
使用Vue 3和Nginx打包和部署Vue.js项目的一般步骤
前端·vue.js·nginx
SmartBoyW4 小时前
CSS弹性布局(Flexbox)学习笔记:从零开始搞懂弹性布局
前端·javascript
用户69371750013844 小时前
从代码生产者到 AI 协作者:软件工程师的角色重构
android·前端·后端
嘟嘟07174 小时前
搞懂 useState 从原生 DOM 到 React 惰性初始化的完整链路
前端·react.js·编程语言