CVE-2021-23490 (published 2021-12-24T20:15Z)

The package parse-link-header before 2.0.0 are vulnerable to Regular Expression Denial of Service (ReDoS) via the checkHeader function.

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/thlorenz/parse-link-header
commit_details: repo_url: https://github.com/thlorenz/parse-link-header
author: Assaf Ben Josef
author_date: 2021-12-16 17:32:52+02:00
msg: Limit linkHeader length, throw error if exceeds (#25)

* Limit linkheader length, add checkHeader func, update documentation

* indentation
repository: repo_url: https://github.com/thlorenz/parse-link-header
repo_name: thlorenz/parse-link-header
description: Parses a link header and returns paging information for each contained link.
repo_language: JavaScript
owner: thlorenz
file_changes: filename: README.md
change_type: ModificationType.MODIFY
diff: @@ -46,6 +46,14 @@ console.log(parsed);
 Parses the given link header containing [web links](http://tools.ietf.org/html/rfc5988) and returns an object keyed by
 the `rel` property that contains information about each link.
 
+### Environmental Variables
+
+To avoid redundantly parsing of extremely long (invalid) input, the package uses 2 env variabes:
+
+`PARSE_LINK_HEADER_MAXLEN` - Sets the number of characters the input should be limited to - longer inputs will not be handled. Defaults to `2000`.
+
+`PARSE_LINK_HEADER_THROW_ON_MAXLEN_EXCEEDED` - Defines behavior for when the `PARSE_LINK_HEADER_MAXLEN` parameter is exceeded. if defined, an error will be thrown; if it's `null`, the function fails silently by returning `null`. Defaults to `null`.
+
 ### Formatting a link header
 
 The purpose of this module is to parse the link header information. To format an object generated by this module back to the link header string, use the [format-link-header](https://github.com/jonathansamines/format-link-header) module.

programming_language: Markdown
filename: index.js
change_type: ModificationType.MODIFY
diff: @@ -4,6 +4,9 @@ var qs = require('querystring')
   , url = require('url')
   , xtend = require('xtend');
 
+const PARSE_LINK_HEADER_MAXLEN = parseInt(process.env.PARSE_LINK_HEADER_MAXLEN) || 2000;
+const PARSE_LINK_HEADER_THROW_ON_MAXLEN_EXCEEDED = process.env.PARSE_LINK_HEADER_THROW_ON_MAXLEN_EXCEEDED != null
+
 function hasRel(x) {
   return x && x.rel;
 }
@@ -46,8 +49,21 @@ function parseLink(link) {
   }
 }
 
+function checkHeader(linkHeader){
+  if (!linkHeader) return false;
+
+  if (linkHeader.length > PARSE_LINK_HEADER_MAXLEN) {
+    if (PARSE_LINK_HEADER_THROW_ON_MAXLEN_EXCEEDED) {
+      throw new Error('Input string too long, it should be under ' + PARSE_LINK_HEADER_MAXLEN + ' characters.');
+    } else {
+        return false;
+      }
+  }
+  return true;
+}
+
 module.exports = function (linkHeader) {
-  if (!linkHeader) return null;
+  if (!checkHeader(linkHeader)) return null;
 
   return linkHeader.split(/,\s*</)
    .map(parseLink)

programming_language: JavaScript
filename: parse-link-header.js
change_type: ModificationType.MODIFY
diff: @@ -186,3 +186,21 @@ test('parsing a proper link header with matrix parameters', function (t) {
   )
   t.end()
 })
+
+test('parsing an extremely long link header', function (t) {
+  function payload (n) {
+    var ret = ""
+    for (var i = 0; i < n; i++) {
+      ret += " "
+    }
+    return ret
+    }
+  var linkHeader = '; rel="' + payload(10000) + '",'
+
+  t.equal(
+      parse(linkHeader)
+    , null
+    , 'correctly returns null when dealing with an extremely long link header'
+  )
+  t.end()
+})

programming_language: JavaScript