CVE-2021-3795 (published 2021-09-15T17:15Z)

semver-regex is vulnerable to Inefficient Regular Expression Complexity

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-1333
cwe_name: Inefficient Regular Expression Complexity
description: The product uses a regular expression with an inefficient, possibly exponential worst-case computational complexity that consumes excessive CPU cycles.
extended_description: Some regular expression engines have a feature called "backtracking". If the token cannot match, the engine "backtracks" to a position that may result in a different token that can match.
                Backtracking becomes a weakness if all of these conditions are met:
                
                    The number of possible backtracking attempts are exponential relative to the length of the input.
                    The input can fail to match the regular expression.
                    The input can be long enough.
                
		
		  Attackers can create crafted inputs that
		  intentionally cause the regular expression to use
		  excessive backtracking in a way that causes the CPU
		  consumption to spike.
		
            
            

Fix information:
repo_url: https://github.com/sindresorhus/semver-regex
commit_details: repo_url: https://github.com/sindresorhus/semver-regex
author: Sindre Sorhus
author_date: 2021-09-11 17:07:12+07:00
msg: Fix ReDoS vulnerability
repository: repo_url: https://github.com/sindresorhus/semver-regex
repo_name: sindresorhus/semver-regex
description: Regular expression for matching semver versions
repo_language: JavaScript
owner: sindresorhus
file_changes: filename: index.js
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,3 @@
 export default function semverRegex() {
-	return /(?<=^v?|\sv?)(?:(?:0|[1-9]\d*)\.){2}(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|[\da-z-]*[a-z-][\da-z-]*)(?:\.(?:0|[1-9]\d*|[\da-z-]*[a-z-][\da-z-]*))*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?\b/gi;
+	return /(?:(?<=^v?|\sv?)(?:(?:0|[1-9]\d{0,9})\.){2}(?:0|[1-9]\d{0,9})(?:-(?:0|[1-9]\d*?|[\da-z-]*?[a-z-][\da-z-]*?){0,100}(?:\.(?:0|[1-9]\d*?|[\da-z-]*?[a-z-][\da-z-]*?))*?){0,100}(?:\+[\da-z-]+?(?:\.[\da-z-]+?)*?){0,100}\b){1,200}/gi;
 }

programming_language: JavaScript
filename: readme.md
change_type: ModificationType.MODIFY
diff: @@ -26,7 +26,7 @@ semverRegex().exec('unicorn 1.0.0 rainbow')[0];
 //=> ['1.0.0', '2.1.3']
 ```
 
-**Note:** For versions coming from user-input, it's up to you to truncate the string to a sensible length to prevent abuse. For example, 100 length.
+**Note:** For versions coming from user-input, you are recommended to truncate the string to a sensible length to prevent abuse. For example, 100 length.
 
 ## Related
 

programming_language: Markdown
filename: test.js
change_type: ModificationType.MODIFY
diff: @@ -12,7 +12,8 @@ const fixtures = [
 	'2.7.2-foo+bar',
 	'1.2.3-alpha.10.beta',
 	'1.2.3-alpha.10.beta+build.unicorn.rainbow',
-	'foo 0.0.0 bar 0.0.0'
+	'foo 0.0.0 bar 0.0.0',
+	'99999.99999.99999'
 ];
 
 test('matches semver versions on test', t => {
@@ -110,4 +111,12 @@ test('invalid version does not cause catatrophic backtracking', t => {
 		`v1.1.3-0aa${postfix}$`,
 		semverRegex()
 	);
+
+	for (let index = 1; index <= 50000; index++) {
+		const start = Date.now();
+		const fixture = `0.0.0-0${'.-------'.repeat(index)}@`;
+		semverRegex().test(fixture);
+		const difference = Date.now() - start;
+		t.true(difference < 10, `Execution time: ${difference}`);
+	}
 });

programming_language: JavaScript