marked icon indicating copy to clipboard operation
marked copied to clipboard

nested lists `Maximum call stack size exceeded`

Open UziTech opened this issue 6 years ago • 5 comments

I found another security issue trying to get nested lists to fail with a recursion error similar to #1462

const marked = require('marked');

const iterations = 300;
let spaces = 0;
let markdown = '';
for (let i = 0; i < iterations; i++) {
  markdown += ' '.repeat(spaces) + '- a\n';
  spaces += 2;
}

marked(markdown);

300 iterations takes about 3 seconds 600 iterations takes about 40 seconds

UziTech avatar Apr 12 '19 16:04 UziTech

commonmark.js has a similar issue https://github.com/commonmark/commonmark.js/issues/160

UziTech avatar Apr 12 '19 17:04 UziTech

A more straightforward way to get a recursion error with nested lists is marked('- '.repeat(5000) + 'a').

andersk avatar Apr 17 '19 18:04 andersk

@andersk good call, looks like the DoS is in the number of characters. but we still have an issue with Maximum call stack size exceeded.

I'm not sure this one will be as easy to fix as blockquote since nested lists are not always the only thing in the list item.

We might just have to limit the number of nested lists.

UziTech avatar Apr 17 '19 19:04 UziTech

Looks like the list regex needs to be fixed or replaced with javascript.

x13machine avatar Apr 28 '19 07:04 x13machine

In this case, it isn't a problem with a regex. It is a problem with using recursion in the lexer. The solution would be to use regex and loop like in the block quote fix.

For now I think this is a case where failing is fine because it doesn't cause a redos attack and it is very unlikely someone would legitimately have 5000 nested lists.

UziTech avatar May 03 '19 20:05 UziTech