Coordinated Disclosure Timeline

Summary

A user of the system can provide an email address containing a specifically crafted string that will trigger a ReDoS vulnerability when checking out an order.

Product

solidus

Tested Version

v2.10.5

Issue details

The Rails app has an email validator class (core/lib/spree/core/validators/email.rb#L15) that matches a given email against the following regex:

EMAIL_REGEXP = /\A([^@\.]|[^@\.]([^@\s]*)[^@\.])@([^@\s]+\.)+[^@\s]+\z/

This is vulnerable to a ReDoS attack, since the ([^@\s]+\.)+ part can match a substring like a.a. in more than one way. So, with many repetitions of a., we can make the regex engine set up exponentially many paths through the NFA, and then a trailing @ will force it to backtrack to try all of them.

irb(main):018:0> EMAIL_REGEXP.match "a@a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.@"
processing time: 54.293660s
=> nil

Impact

Denial of Service

Resources

Proof of concept

To demonstrate an exploit, run a sample Solidus Rails app in Docker:

$ docker run --rm -it -p 3000:3000 solidusio/solidus-demo:latest

Then, in a browser:

After a long wait, the page will finish loading and show an error that the email is invalid. In the terminal you’ll see a message like Completed 200 OK in 42398ms showing that we made the server process spin the CPU for 42 seconds.

If we use a longer attack string, we can make it take even longer. I got tired of waiting before seeing if it would ever time out.

Credit

This issue was discovered by @nickrolfe (Nick Rolfe) from the GitHub CodeQL team.

Contact

You can contact the GHSL team at securitylab@github.com, please include GHSL-2021-099 in any communication regarding this issue.