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

相关推荐
莪_幻尘2 小时前
你的 AI Skill 越多越蠢?Token 上下文爆炸的求生指南
前端·ai编程
lichenyang4532 小时前
从 has.echo 到异步 API 注册表:一次 ASCF API 回调不触发的排查复盘
前端
林瞅瞅3 小时前
Nuxt3 项目部署 Nginx 防盗链后特定 JS 文件 403 问题修复方案
前端
kyriewen3 小时前
别再每次都 Google 了:我整理了前端日常最常踩的 10 个 Git 坑,附速查表
前端·javascript·git
一颗奇趣蛋3 小时前
Web 视频开发完全指南:从入门到精通
前端
非洲农业不发达3 小时前
windows终端体验大升级,让你拥有macos级别的美化
前端·后端
妙码生花4 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十七):登录接口完善,登录页接口整合,解决跨域
前端·后端·ai编程
唐诗4 小时前
改 3 行配置,我的 Tauri dev 冷启动从 100 秒干到 4 秒
前端·客户端
SmartBoyW4 小时前
深入ECMAScript规范:彻底搞懂JS隐式类型转换与底层ToPrimitive机制
前端·javascript
牧艺4 小时前
Cursor Rules / Skills 分层设计:让 Agent 像「团队新同事」
前端·人工智能·cursor