VDB
Sign up
MEDIUM6.1

GHSA-qx2v-qp2m-jg93

PostCSS has XSS via Unescaped </style> in its CSS Stringify Output

Quick fix

GHSA-qx2v-qp2m-jg93 — postcss: upgrade to the fixed version with the command below.

npm install postcss@8.5.10

Details

# PostCSS: XSS via Unescaped `</style>` in CSS Stringify Output

## Summary

PostCSS v8.5.5 (latest) does not escape `</style>` sequences when stringifying CSS ASTs. When user-submitted CSS is parsed and re-stringified for embedding in HTML `<style>` tags, `</style>` in CSS values breaks out of the style context, enabling XSS.

## Proof of Concept

```javascript const postcss = require('postcss');

// Parse user CSS and re-stringify for page embedding const userCSS = 'body { content: "</style><script>alert(1)</script><style>"; }'; const ast = postcss.parse(userCSS); const output = ast.toResult().css; const html = `<style>${output}</style>`;

console.log(html); // <style>body { content: "</style><script>alert(1)</script><style>"; }</style> // // Browser: </style> closes the style tag, <script> executes ```

**Tested output** (Node.js v22, postcss v8.5.5): ``` Input: body { content: "</style><script>alert(1)</script><style>"; } Output: body { content: "</style><script>alert(1)</script><style>"; } Contains </style>: true ```

## Impact

Impact non-bundler use cases since bundlers for XSS on their own. Requires some PostCSS plugin to have malware code, which can inject XSS to website.

## Suggested Fix

Escape `</style` in all stringified output values: ```javascript output = output.replace(/<\/(style)/gi, '<\\/$1'); ```

## Credits Discovered and reported by [Sunil Kumar](https://tharvid.in) ([@TharVid](https://github.com/TharVid))

Are you affected?

Enter the version of the package you're using.

Affected packages

npm/postcss
Introduced in: 0Fixed in: 8.5.10
Fixnpm install postcss@8.5.10

References