Devise, Open Redirect via Referer in Timeoutable, CVE-2020-xxxx (Medium)

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).

  1. Form POST triggers session timeout → redirect to Referer (evil.com/phish).
  2. 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

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top