3
const str = 'Test test1 test2'
const pat = 'test';
const re = new RegExp(pat, 'i'); //Found non-literal argument to RegExp Constructoreslint(security/detect-non-literal-regexp)
const result = str.replace(re, "abc");
console.log(result);

Please help me to solved this.Thanking you in advance!

Deep
  • 525
  • 3
  • 8
  • [Here is the rule](https://github.com/nodesecurity/eslint-plugin-security/blob/master/README.md#detect-non-literal-regexp). Either abide by it and use a literal string, or disable it. – VLAZ Oct 22 '20 at 10:39
  • @VLAZ Can you please provide solution (Code sample appreciated) to remove this error. As according to your provided link it can be an issue for long running regular expression. But here I don't see that case. So what can be done to resolve this error? – Jimesh Oct 22 '20 at 10:46
  • 1
    It's a linting error. Either you've set it up so this code is treated as problematic or somebody else did. The rule explains what it looks for - using a variable in the RegExp constructor. A correct invocation would thus be `new RegExp('test', 'i')`, so that's how you fix it. The only other alternative is disabling the rule - either globally or for this file/line. The solution is *the same* for any linting rule problem you get - identify what the rule considers wrong and either change your code or change the rule. – VLAZ Oct 22 '20 at 10:50
  • So, use `const re = /test/i;` – Wiktor Stribiżew Oct 22 '20 at 11:10
  • the rule detects cases where the regex could be constructed using user input from a form field. Using a literal string in the Regexp constructor or using a regexp literal `//` (as Wiktor suggests) prevents this. If you need to use user input you have to sanitize the string first: remove all characters other than `[a-zA-Z0-9_]` this can be done with a regex with literal string – rioV8 Oct 22 '20 at 13:11
  • Does `const re = new RegExp(${pat}, 'i');` work? – Mark Oct 22 '20 at 20:36

2 Answers2

3

ESLint detect-non-literal-regexp rule explains the logic behind it:

Detects RegExp(variable), which might allow an attacker to DOS your server with a long-running regular expression.

More information: Regular Expression DoS and Node.js

If you need to build regexps dynamically, disable the rule and use your code. Maybe implement the regex match cancel timeout feature.

If you have a simple static pattern like in the question, use regex literal notation:

const re = /test/i;
Ryszard Czech
  • 18,032
  • 4
  • 24
  • 37
0
rules:
  - id: eslint.detect-non-literal-regexp
    patterns:
      - pattern: |
          new RegExp($ARG, ...)
      - pattern-not: |
          new RegExp("...", ...)

See how it's checking for the new RegExp($ARG, ...) pattern?

Here's how to circumvent the rule:

const pat = 'test';
const RE = RegExp;
const re = new RE(pat, 'i');
Ron Roth
  • 1
  • 1