5

I have a regex that looks like this /^[A-Za-z.,'-]([A-Za-z.,' -]*[A-Za-z.,'-])?$/

I've recently added the eslint-config-security plugin and it has flagged the above regex as unsafe due to the detect-unsafe-regex rule.

It does not say why it is unsafe.

Can anyone tell me why this is unsafe and what I can do to fix it?

It runs this package

dagda1
  • 26,856
  • 59
  • 237
  • 450

2 Answers2

7

Details: Finally got some time so I'll explain what's happening here. The reason is catastrophic backtracking. I'll take the example from the blog:

You are doing something like this (x+x+)+y when doing this ([A-Za-z.,' -]*[A-Za-z.,'-]) x+x+ could've been limited to x+ but in your case, there is little difference between both the x. So a solution for you is to use ([A-Za-z.,' -]* ?) this way regex engine won't break down the system.

What happens is stated below from the blog:

Consider the regular expression (x+x+)+y. Let's see what happens when you apply this regex to xxxxxxxxxxy. The first x+ will match all 10 x characters. The second x+ fails. The first x+ then backtracks to 9 matches, and the second one picks up the remaining x. The group has now matched once. The group repeats but fails at the first x+.When y fails, the regex engine backtracks. The group has one iteration it can backtrack into. The second x+ matched only one x, so it can't backtrack. But the first x+ can give up one x. The second x+ promptly matches xx. The group again has one iteration, fails the next one, and the y fails. When y fails, the regex engine backtracks. The group has one iteration it can backtrack into. The second x+ matched only one x, so it can't backtrack. But the first x+ can give up one x. The second x+ promptly matches xx. The group again has one iteration, fails the next one, and the y fails. Backtracking again, the second x+ now has one backtracking position, reducing itself to match x. The group tries a second iteration. The first x+ matches but the second is stuck at the end of the string. Backtracking again, the first x+ in the group's first iteration reduces itself to 7 characters. The second x+ matches xxx. Failing y, the second x+ is reduced to xx and then x.

If you try this regex on a 10x string in RegexBuddy's debugger, it'll take 2558 steps to figure out the final y is missing. For an 11x string, it needs 5118 steps. For 12, it takes 10238 steps. Clearly we have an exponential complexity of O(2^n) here. At 21x the debugger bows out at 2.8 million steps, diagnosing a bad case of catastrophic backtracking.

Regex engines (like .NET) will keep going forever, while others will crash with a stack overflow (like Perl, before version 5.10). Stack overflows are particularly nasty on Windows since they tend to make your application vanish without a trace or explanation.

Here's the discussion about these plugins

And great blog showing what's wrong

Black Mamba
  • 13,632
  • 6
  • 82
  • 105
4

It seems that plugin uses word unsafe to demonstrate a regex which is likely to cause a catastrophic backtracking:

detect potentially catastrophic exponential-time regular expressions by limiting the star height to 1

and your regex may cause it which you can see here in action. Please read this answer to have a better insight into this problem.

revo
  • 47,783
  • 14
  • 74
  • 117