1

FindBugs flagged the following email address validation regex as vulnerable to DoS:

^[\w!#$%&'*+/=?`{|}~^-]+(?:\.[\w!#$%&'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}$

Here's an easier to read version that substitutes CHARS for \w!#$%&'*+/=?`{|}~^-:

[CHARS]+(?:\.[CHARS]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}

Based on my reading of the OWASP ReDoS page, this isn't actually vulnerable. I can't see a way to ambiguously apply the pattern, because the repetition inside the groups doesn't apply to the period character, which ought to result in a canonical application of the pattern.

Have I misunderstood the threat here? Can anyone spot a way to abuse this pattern?

1

Tricky one! I can't seem to trigger the exponential complexity this (\.[CHARS]+)* pattern should introduce. I can make it be a little slow with a huge string (a few megabytes), but I guess that is to be expected with any regular expression. In Python:

import time, re
t=time.time()
print(re.match(r'^[\w!#$%&\'*+/=?`{|}~^-]+(\.[\w!#$%&\'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}$', 'a.'+'xb'*2500000+'test@example.com'))
print(time.time()-t)
t=time.time()
print(re.match(r'^[\w!#$%&\'*+/=?`{|}~^-]+(\.[\w!#$%&\'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}$', 'ax'+'.b'*2500000+'test@example.com'))
print(time.time()-t)

In the first test, we supply a long string where the xb pattern is repeated. This matches just the first part (namely, [CHARS]+) and not the second (namely, (\.[CHARS]+)*)). The second test does the opposite: it repeats the '.b' pattern which matches the second part a lot of times (where the backtracking should be) and not the first.

As output, you can see the difference in time it takes:

0.06872129440307617
0.3483853340148926

Both strings are equally long, so the pattern does take some more time.

Usually, one would use the second pattern and then make the end not match, so remove the .com part or something. The regex engine would start to backtrack and take exponentially longer with each iteration. I'm not sure why that does not happen here.

So far as I can see, you might be safe by just limiting the input length to a few kilobytes. But I am probably just too stupid to trigger it; using a pattern that is known to be vulnerable is just asking for someone to come along and figure it out ;-)

  • "the exponential complexity this (\.[CHARS]+)* pattern should introduce" > Doesn't the period prevent the complexity? The examples given in the OWASP page look more like ([CHARS]+)*, which is ambiguous. However in this case, because CHARS doesn't include a period as a possible character, I think there is no complexity here? – Duncan Jones Mar 1 at 12:06
  • @DuncanJones Good point. If I remove the dot and update the test strings accordingly, I can indeed trigger the vuln. So you might be right, but I'd still avoid the regex if possible. (And that's besides the point that email regexes are always faulty/annoying, but that's a different topic covered in other questions on other stackexchange sites.) – Luc Mar 1 at 12:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.