文章总结: 本文分析WordPress核心CVE-2026-93485未认证存储型XSS漏洞,可升级为RCE。漏洞源于wpautop()正则不感知引号导致过滤器级联变换,攻击者可通过评论零点击触发。影响4.7至7.1版本,官方已发布修复。建议立即升级、排查异常文件、关闭评论审核,并部署WAF拦截恶意评论。
综合评分: 90
文章分类: 漏洞分析,WEB安全,代码审计,应急响应,安全工具
CVE-2026-93485 | WordPress Comment2Shell存储型XSS可导致RCE漏洞(POC)
alicy
alicy
信安百科
2026年9月29日 09:00
河北
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
免责声明:本文漏洞技术细节均来源于公开可查证的安全研究资料,仅用于安全研究与防御加固参考,不构成任何攻击指引。
#
0x00、前言
WordPress 驱动着全球超过 43% 的网站,是最广泛部署的内容管理系统,其核心代码的任何缺陷都可能波及数百万站点。
2026 年 9 月 17 日,WordPress 发布 7.1.1 安全与维护版本,一次性修复 11 个安全问题,其中最受瞩目的是核心函数 wpautop() 的未认证存储型 XSS 漏洞(CVE-2026-93485)。
发现者 Rafie Muhammad 最初将其命名为 Comment2Shell,后应 WordPress 维护者要求更名为 Comment2XSS——以强调 RCE 只是”潜在”升级路径。
攻击者只需留下一条看似无害的匿名评论,脚本便会在页面加载瞬间零点击触发,若管理员恰好访问,服务器可能被完整接管。
#
0x01、漏洞描述
漏洞根源是评论”保存时消毒、展示时重排“两阶段的语义错位:
保存阶段由 KSES 按白名单消毒,展示阶段由 comment_text 过滤链重写 HTML。
攻击者在白名单允许的 blockquote 的 cite 属性中放入换行符,展示阶段 wpautop() 将其替换为自带 > 字符的占位注释,其不感知引号语境的正则在属性值内部提前截断、注入 <p>;叠加 wptexturize() 的引号转换差异,攻击者文本最终被浏览器解析为 onfocus 等真实事件属性。
利用条件:评论须出现在页面上(默认配置存在多条绕过审核的路径);触发零点击;升级 RCE 需登录管理员访问该页面。
#
0x02、CVE 编号
| 项目 | 内容 |
| — | — |
| CVE 编号 | CVE-2026-93485(Comment2XSS,初名 Comment2Shell) |
| 漏洞类型 | 未认证存储型 XSS(CWE-79),可升级至潜在 RCE |
| CVSS 评分 | 7.1 / HIGH(CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:L) |
| 受影响组件 | WordPress Core —— wpautop()(wp-includes/formatting.php) |
#
0x03、影响版本
该漏洞影响 WordPress 4.7 至 7.1 的全部 25 个受支持版本分支,修复已回移至最老的 4.7.36。各分支修复版本如下:
注意:WordPress 官方仅积极支持最新主版本,旧分支只接收安全回移;开启自动后台更新的站点已自动完成升级。7.1.1 同时修复了另外 10 个安全问题,但此漏洞是其中唯一无需任何账号即可触达的。
#
0x04、漏洞详情
4.1 两阶段处理与过滤器链
用户可以评论形式提交原始 HTML,但 wp-includes/kses.php 的白名单只放行七类标签:a、abbr、acronym、blockquote[cite]、del[datetime]、q[cite] 和 code。展示阶段,评论文本依次经过 comment_text 上注册的六个过滤器,每个都会重写 HTML——漏洞正藏于这些重写的级联之中:
// wp-includes/default-filters.php:225-230
add_filter( 'comment_text', 'wptexturize' ); // 直引号→弯引号
add_filter( 'comment_text', 'convert_chars' );
add_filter( 'comment_text', 'make_clickable', 9 );
add_filter( 'comment_text', 'force_balance_tags', 25 );
add_filter( 'comment_text', 'convert_smilies', 20 );
add_filter( 'comment_text', 'wpautop', 30 ); // 换行转段落(漏洞核心)
4.2 五步级联变换:从良性 HTML 到活的事件属性
研究者指出:”这次利用的关键正是 blockquote 的 cite 属性中的换行符(\n),它引发了过滤器的不安全级联变换。”完整变换链如下:
提交: <blockquote cite="a\nb"><code>x" onfocus=alert(document.domain) autofocus tabindex=0</code></blockquote>
(1) KSES 放行 —— blockquote[cite] 在白名单内,\n 不在再编码映射中
(2) wpautop(): 标签内换行→占位注释 cite="a <!-- wpnl --> b"
(3) wpautop(): 正则 <p><blockquote([^>]*)> 在占位注释的 > 处提前截断
<p> 被写入 cite 属性内部 → cite="a<p> b"
(4) wptexturize(): 注入的 <p> 形成标签边界,cite 收尾引号→”
<code> 内引号因豁免规则原样保留
(5) 浏览器最终解析:
<blockquote cite="a<p> b”><code>x" onfocus=alert(document.domain) autofocus tabindex=0</code></p></blockquote>
onfocus / autofocus / tabindex 成为真实属性,页面加载即触发,零点击
(代码较长,可左右滑动查看完整内容)
各步骤要点:
第 1 步,KSES 的属性再编码映射只覆盖 &、<、>、’、” 五个语法字符,换行符不在其中,因此cite="a\nb"或其编码形式cite="a b"均可入库。
第 2 步,wpautop() 把标签内换行替换为占位注释<!-- wpnl -->——正如 Patchstack 所评:”WordPress 自己供给了攻击所需的 > 字符。”
第 3 步是致命一环:wpautop() 为 blockquote 前置空行并包上<p>,随后用正则|<p><blockquote([^>]*)>|i把<p>移入 blockquote 内部,但捕获组[^>]*无法跨越>,在占位注释处提前截断,<p>被直接写进 cite 属性值中间。
第 4 步,块主题默认经get_the_block_template_html()调用 wptexturize()(部分经典主题如 Twenty Twenty-One 经the_content()同样调用);注入的<p>成了标签边界,cite 的收尾引号被当作普通文本转为弯引号实体,而<code>内的引号因豁免列表(pre、code、kbd、style、script、tt)原样幸存。
第 5 步,浏览器将 onfocus、autofocus、tabindex 解析为 blockquote 的真实属性——autofocus 使元素在页面加载中获得焦点,onfocus 随即自动触发,全程无需任何点击。研究者强调:换行与引号缺一不可。
4.3 从 XSS 到 RCE:插件上传的最后一跃
事件处理器在页面加载者的会话中运行。若来访者是登录管理员,脚本即可触达插件安装器——上传端点检查的 upload_plugins 能力会被映射为管理员持有的 install_plugins。这是从管理员上下文 XSS 到服务器代码执行的已知通路:
[1] fetch 读取 plugin-install.php?tab=upload 页面,提取表单中的 _wpnonce
[2] 内存构建单文件插件 zip,内嵌 PHP 命令执行逻辑
[3] FormData 携带 nonce 与 zip,POST 至 update.php?action=upload-plugin
[4] 无需激活:插件文件已落盘,路径可直接访问,参数即待执行命令
(代码较长,可左右滑动查看完整内容)
研究者特别指出:恶意插件甚至无需激活——文件已写入磁盘,插件路径可直接访问,web shell 立即应答。这也是当初命名 Comment2Shell、后依维护者建议改为 Comment2XSS 的原因:XSS 已获完整验证,RCE 则是通过已知通路可达的”潜在”结果。
4.4 一行补丁:让正则感知引号
修复仅改动一行——将 <p><blockquote> 重写正则升级为引号感知子模式,使其能够跨越引号属性值内部的 >:
// 修复前(WordPress <= 7.1),wp-includes/formatting.php:563
$text = preg_replace( '|<p><blockquote([^>]*)>|i', '<blockquote$1><p>', $text );
// 修复后(WordPress 7.1.1)—— 引号感知子模式
$text = preg_replace( '!<p><blockquote((?:[^>"\']|"[^"]*"|\'[^\']*\')*)>!i', '<blockquote$1><p>', $text );
(代码较长,可左右滑动查看完整内容)
新子模式 (?:[^>"\']|"[^"]*"|\'[^\']*\')* 允许捕获完整跨越引号值内的 >,<p> 落在真正闭合标签的 > 之后;正则分隔符由 | 改为 !,因子模式自身已含 |。一行即够,因为这处重写是 wpautop() 中唯一向标签内部插入内容的位置。
0x05、个人观察与判断
1、对设计缺陷的点评:wpautop() 是核心里唯一不解析 HTML、纯靠正则改写标记的内容过滤器,正则不感知引号语境出事只是时间问题。Patchstack 的评价一针见血——结构性 API(如 HTML Tag Processor)才是正道。
2、对行业趋势的思考:WordPress 核心今年接连曝出 wp2shell、XSS2Shell、Click2Shell 到 Comment2XSS,”匿名注入 + 管理员会话 + 插件上传”已成标准化 RCE 公式,核心渲染管线的审计价值高于插件生态。
3、可落地的排查建议:立即升级到所在分支修复版;排查 wp-content/plugins 下陌生目录与近期新增 PHP 文件;暂无法升级时全站关闭评论并开启全量人工审核;WAF 可拦截 cite 属性含换行的评论提交。
#
0x06、参考链接
1、https://idnsec.com/research/comment2shell-zero-click-pre-auth-xss-to-rce-in-wordpress-core/
研究者 Rafie Muhammad 原始技术分析(核心技术分析)
2、https://wordpress.org/news/2026/09/wordpress-7-1-1-maintenance-and-security-release/
WordPress 官方 7.1.1 安全与维护版本公告(厂商公告)
3、https://www.patchstack.com/articles/wordpress-7-1-1-maintenance-and-security-release/
Patchstack 版本分析与修复解读(CNA 官方解读)
— END —
❤ 如果觉得有帮助,点个红心支持一下吧。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:信安百科 alicy
alicy《CVE-2026-93485 | WordPress Comment2Shell存储型XSS可导致RCE漏洞(POC)》