Skip to content

ReDoS vulnerable when unknown-options-as-args is set #386

Description

@robmcl4

yargs-parser@20.2.7 appears vulnerable to regular expression denial-of-service (ReDoS) when unknown-options-as-args is set to true and an attacker can invoke the parser with arguments of the form ----....----a. See proof-of-concept below:

const parse = require('yargs-parser');
for (let i=0; i < 100000; i += 1000)
{
    const s = (new Array(i).fill('-').join('')) + 'a';
    const start = +new Date();
    parse([s], {configuration: {'unknown-options-as-args': true}});
    const end = +new Date();
    console.log(i + '\t' + (end - start));
}

See the output of above graphed below, with a power regression overlaid:

image

This appears to be caused by the regexps at yargs-parser.ts lines 977-985. The maximum number of characters in an argument passed by process invocation is quite large, so I recommend fixing this by swapping the regular expressions with these safe replacements.

regexp replacement
^-+([^=]+?)=[\s\S]*$ ^-+([^=-]+?)=[\s\S]*$
^-+([^=]+?)$ ^-+([^=-]+?)$
^-+([^=]+?)-$ ^-+([^=-]+?)-$
^-+([^=]+?\d+)$ ^-+([^=\d-]+?\d+)$
^-+([^=]+?)\W+.*$ ^-+([^=\W-]+?)\W+[^\W+]*$

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions