14 Nov
Open redirect vulnerabilites in Rails apps - Rails Tricks Issue 22
Today, I want to tell you about open redirect vulnerabilities and how to prevent them in a Rails application.
We are talking about an open redirect vulnerability when the application redirects to a URL that a malicious user can control. It can be used for phishing by redirecting users to a fake login page where they enter their credentials.
A typical occurrence of this vulnerability is when a return URL can be controlled via a URL parameter. For instance, if an application redirects to a page after logout and the target is set in a URL parameter.
A typical occurrence of this vulnerability is when a return URL can be controlled via a URL parameter. For instance, if an application redirects to a page after logout and the target is set in a URL parameter.
If an application uses a return_to GET parameter, and accepts a URL like this: example.com/logout?return_to=/, a malicious actor can send a link to example.com/logout?return_to=https://fishingsite.com and the user might not realize that they are not on example.com after they sign out.
Another example is the redirect after a successful login, when you use the HTTP Referer, or a URL parameter. Setting the referer to a malicious one can be done with an extra redirect from the phishing site, or if the web server has a host header injection vulnerability, that can also be utilized.
The good news is, Rails has built-in protection for this issue since version 7, with a follow-up fix in 7.0.4.1, so if you are on a new enough release, all you need to do is to set the following config variable:
# config/application.rb ... config.action_controller.raise_on_open_redirects = true ...
If you set raise_on_open_redirects to true, all redirect helpers will prevent open redirections. You might still want to allow a certain redirect to external hosts though, and in that scenario, you can call redirect_to with allow_other_host: true.
If you are stuck on an older version of Rails, you should pass any user-controlled redirect paths through a whitelist.
That’s it for today, until next time!