CVE-2021-3794 (published 2021-09-15T13:15Z)

vuelidate 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: NVD-CWE-Other
cwe_name: Other
description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/vuelidate/vuelidate
commit_details: repo_url: https://github.com/vuelidate/vuelidate
author: Dobromir Hristov
author_date: 2021-09-10 10:20:41+03:00
msg: fix(validators): update the url validator, to reduce potential ReDos attacks (#933)
repository: repo_url: https://github.com/vuelidate/vuelidate
repo_name: vuelidate/vuelidate
description: Simple, lightweight model-based validation for Vue.js
repo_language: JavaScript
owner: vuelidate
file_changes: filename: url.spec.js
change_type: ModificationType.MODIFY
diff: @@ -10,6 +10,11 @@ describe('url validator', () => {
     'HTTP://FOO.COM/BLAH_BLAH',
     'HTTP://FOO.COM/blah_blah',
     'http://foo.com/blah_blah/',
+    /** domains ending with a dot at the end are valid, {@see http://www.dns-sd.org/trailingdotsindomainnames.html} */
+    'http://www.foo.bar./',
+    'http://www.foo.bar.',
+    'http://foo.bar.',
+    'http://foo.bar./',
     'http://foo.com/blah_blah_(wikipedia)',
     'http://foo.com/blah_blah_(wikipedia)_(again)',
     'http://www.example.com/wpstyle/?p=364',
@@ -40,7 +45,7 @@ describe('url validator', () => {
     'http://مثال.إختبار',
     'http://例子.测试',
     'http://उदाहरण.परीक्षा',
-    "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com",
+    'http://-.~_!$&\'()*+,;=:%40:80%2f::::::@example.com',
     'http://1337.net',
     'http://a.b-c.de',
     'http://223.255.255.254'
@@ -80,21 +85,16 @@ describe('url validator', () => {
     'http://123.123.123',
     'http://3628126748',
     'http://.www.foo.bar/',
-    'http://www.foo.bar./',
     'http://.www.foo.bar./',
     'http://10.1.1.1',
     'http://10.1.1.254'
   ]
 
-  correctUrls.forEach((urlString) => {
-    it(`should validate correct url ${urlString}`, () => {
-      expect(url(urlString)).toBe(true)
-    })
+  it.each(correctUrls)('should validate correct url %s', (urlString) => {
+    expect(url(urlString)).toBe(true)
   })
 
-  incorrectUrls.forEach((urlString) => {
-    it(`should not validate incorrect url ${urlString}`, () => {
-      expect(url(urlString)).toBe(false)
-    })
+  it.each(incorrectUrls)('should not validate incorrect url %s', (urlString) => {
+    expect(url(urlString)).toBe(false)
   })
 })

programming_language: Python
filename: url.js
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,8 @@
 import { regex } from '../common'
 
-const urlRegex = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i
+/**
+ * Regex taken from {@link https://gist.github.com/dperini/729294}
+ */
+const urlRegex = /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i
 
 export default regex(urlRegex)

programming_language: TypeScript