Listen to this Post
How the CVE works:
The vulnerability exists in Devise’s FailureApp when the Timeoutable module is enabled.
For non-GET requests (POST, PUT, PATCH, DELETE) that trigger a session timeout,
FailureAppredirect_url returns request.referrer – the HTTP Referer header.
This header is fully attacker-controlled via a malicious external page.
Unlike the GET timeout path which uses the server-side attempted_path,
the non-GET path does not validate the referrer before redirecting.
Devise’s store_location_for method (used elsewhere) sanitizes URLs via extract_path_from_location,
but this protection is not applied in the timeout redirect for non-GET requests.
An attacker hosts a page with an auto-submitting cross-origin form targeting the vulnerable app.
When a victim with an expired session visits that page, the form submits (e.g., POST)
to the app, triggering a timeout response.
The app redirects to the attacker-controlled Referer URL without validation.
Rails’ built-in open-redirect protection does not apply because Devise::FailureApp
is an ActionController::Metal app with its own isolated configuration.
Thus, the victim is silently redirected to an arbitrary external domain,
bypassing browser phishing warnings. The redirect appears from the trusted app’s domain.
The patched version (Devise 5.0.4) replaces request.referrer with safe_request.referrer
and adds host validation.
dailycve form:
Platform: Ruby on Rails
Version: Devise <5.0.4
Vulnerability: Open redirect
Severity: Medium
Date: 2020-08-15
Prediction: Patch already available
What Undercode Say:
Check Devise version in Gemfile.lock grep devise Gemfile.lock Simulate vulnerable behavior (example curl) curl -X POST https://target-app.com/users/sign_in \ -H "Referer: https://evil.com/phish" \ -H "Cookie: expired_session=..." Monitor redirects in logs tail -f log/development.log | grep "redirect_to"
Exploit:
1. Create HTML page with auto-submitting form:
<form action="https://victim-app.com/private-data" method="POST"> <input type="hidden" name="any" value="data"> </form> <script>document.forms[bash].submit();</script>
2. Victim has expired Devise session (timeout).
- Form POST triggers session timeout → redirect to Referer (evil.com/phish).
- Victim lands on fake login page, credentials stolen.
Protection from this CVE
- Upgrade Devise to >=5.0.4 immediately.
- If upgrade impossible, monkey-patch in initializer:
config/initializers/devise_cve_patch.rb module Devise class FailureApp def redirect_url if warden_message == :timeout flash[:timedout] = true if is_flashing_format? path = if request.get? attempted_path else safe_request.referrer if safe_request.referrer&.start_with?(request.base_url) end path || scope_url else scope_url end end end end
- Remove monkey-patch after upgrade.
- Alternatively, disable Timeoutable if not needed.
Impact
- Phishing via trusted domain redirect.
- Credential theft or malware distribution.
- Bypasses Rails open-redirect protections.
- Affects all non-GET requests with expired sessions.
- No user interaction beyond visiting attacker’s page.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

