CVE-2022-21670 (published 2022-01-10T21:15Z)

markdown-it is a Markdown parser. Prior to version 1.3.2, special patterns with length greater than 50 thousand characterss could slow down the parser significantly. Users should upgrade to version 12.3.2 to receive a patch. There are no known workarounds aside from upgrading.

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

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/markdown-it/markdown-it
commit_details: repo_url: https://github.com/markdown-it/markdown-it
author: Vitaly Puzrin
author_date: 2022-01-08 18:00:47+03:00
msg: Fix possible ReDOS in newline rule.

Co-authored-by: MakeNowJust <make.just.on@gmail.com>
repository: repo_url: https://github.com/markdown-it/markdown-it
repo_name: markdown-it/markdown-it
description: Markdown parser, done right. 100% CommonMark support, extensions, syntax plugins & high speed
repo_language: JavaScript
owner: markdown-it
file_changes: filename: CHANGELOG.md
change_type: ModificationType.MODIFY
diff: @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [12.3.2] - 2022-01-08
+### Security
+- Fix possible ReDOS in newline rule. Thanks to @MakeNowJust.
+
 
 ## [12.3.1] - 2022-01-07
 ### Fixed
@@ -588,6 +592,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Renamed presets folder (configs -> presets).
 
 
+[12.3.2]: https://github.com/markdown-it/markdown-it/compare/12.3.1...12.3.2
 [12.3.1]: https://github.com/markdown-it/markdown-it/compare/12.3.0...12.3.1
 [12.3.0]: https://github.com/markdown-it/markdown-it/compare/12.2.0...12.3.0
 [12.2.0]: https://github.com/markdown-it/markdown-it/compare/12.1.0...12.2.0

programming_language: Markdown
filename: newline.js
change_type: ModificationType.MODIFY
diff: @@ -6,7 +6,7 @@ var isSpace = require('../common/utils').isSpace;
 
 
 module.exports = function newline(state, silent) {
-  var pmax, max, pos = state.pos;
+  var pmax, max, ws, pos = state.pos;
 
   if (state.src.charCodeAt(pos) !== 0x0A/* \n */) { return false; }
 
@@ -20,7 +20,11 @@ module.exports = function newline(state, silent) {
   if (!silent) {
     if (pmax >= 0 && state.pending.charCodeAt(pmax) === 0x20) {
       if (pmax >= 1 && state.pending.charCodeAt(pmax - 1) === 0x20) {
-        state.pending = state.pending.replace(/ +$/, '');
+        // Find whitespaces tail of pending chars.
+        ws = pmax - 1;
+        while (ws >= 1 && state.pending.charCodeAt(ws - 1) === 0x20) ws--;
+
+        state.pending = state.pending.slice(0, ws);
         state.push('hardbreak', 'br', 0);
       } else {
         state.pending = state.pending.slice(0, -1);

programming_language: JavaScript
filename: pathological.js
change_type: ModificationType.MODIFY
diff: @@ -138,5 +138,9 @@ describe('Pathological sequences speed', () => {
     it('autolinks <<<<...<<> pattern', async () => {
       await test_pattern('<'.repeat(400000) + '>');
     });
+
+    it('hardbreak whitespaces pattern', async () => {
+      await test_pattern('x' + ' '.repeat(150000) + 'x  \nx');
+    });
   });
 });

programming_language: TypeScript