Skip to main content

Devise CVE-2026-40295

MEDIUM
URL Redirection to Untrusted Site (Open Redirect) (CWE-601)
2026-05-08 https://github.com/heartcombo/devise GHSA-jp94-3292-c3xv
6.1
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
6.1 MEDIUM
AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Changed
Confidentiality
Low
Integrity
Low
Availability
None

Lifecycle Timeline

3
Source Code Evidence Fetched
May 08, 2026 - 16:17 vuln.today
Analysis Generated
May 08, 2026 - 16:17 vuln.today
CVE Published
May 08, 2026 - 15:41 nvd
MEDIUM 6.1

DescriptionGitHub Advisory

Summary

When the Timeoutable module is enabled in Devise, the FailureApp#redirect_url method returns request.referrer - the HTTP Referer header, which is attacker-controllable - without validation for any non-GET request that results in a session timeout. An attacker who hosts a page with an auto-submitting cross-origin form can cause a victim with an expired Devise session to be redirected to an arbitrary external URL. This contrasts with the GET timeout path (which uses server-side attempted_path) and Devise's own store_location_for mechanism (which strips external hosts via extract_path_from_location), both of which are protected; only the non-GET timeout redirect path is unprotected.

Details

The vulnerable code is in lib/devise/failure_app.rb:

ruby
def redirect_url
  if warden_message == :timeout
    flash[:timedout] = true if is_flashing_format?

    path = if request.get?
      attempted_path
# safe: server-side value from warden options
    else
      request.referrer
# UNSAFE: HTTP Referer header, attacker-controlled
    end

    path || scope_url
  else
    scope_url
  end
end

This is passed directly to redirect_to:

ruby
def redirect
  store_location!
# ...
  redirect_to redirect_url
# redirect_url may be an external attacker URL
end

The GET timeout path uses attempted_path, which is set server-side by Warden and cannot be influenced by the client. The store_location! method also only runs for GET requests, so no session-based protection is applied on POST timeouts.

By contrast, Devise's store_location_for method (used elsewhere) correctly sanitizes URLs via extract_path_from_location, which strips the scheme and host.

Impact

  • Victims with expired sessions who click any attacker-crafted link or visit an attacker page with an auto-submitting form are redirected to an arbitrary external URL.
  • The redirect happens transparently via a trusted domain (the target app's domain), bypassing browser phishing warnings.
  • An attacker can redirect victims to a fake login page to harvest credentials (phishing), or to malicious download sites.

_Note_: Rails' built-in open-redirect protection does not mitigate this issue. Devise::FailureApp is an ActionController::Metal app with its own isolated copy of the relevant redirect configuration, so config.action_controller.action_on_open_redirect = :raise (and the older raise_on_open_redirects setting) do not reach it.

Patches

This is patched in Devise v5.0.4. Users should upgrade as soon as possible.

Workaround

None beyond upgrading. If an upgrade is not immediately possible, the same changes from the patch commit can be applied as a monkey-patch in a Rails initializer (Devise::FailureApp#redirect_url and Devise::Controllers::StoreLocation#extract_path_from_location). Remove the monkey-patch after upgrading.

AnalysisAI

Open redirect in Devise's Timeoutable module allows unauthenticated attackers to redirect users with expired sessions to arbitrary external URLs via an unvalidated HTTP Referer header on non-GET requests. An attacker can host a page with an auto-submitting form to transparently redirect victims through a trusted domain, enabling credential harvesting or malware distribution without triggering browser phishing warnings. Affects Devise versions up to 5.0.3; patched in 5.0.4.

Technical ContextAI

Devise is a flexible authentication solution for Rails that includes a Timeoutable module enabling session expiration. The vulnerability exists in the FailureApp#redirect_url method in lib/devise/failure_app.rb, which handles session timeout redirects. When a non-GET request times out, the method returns request.referrer (the HTTP Referer header) directly without validation. This contrasts with GET timeout handling, which uses attempted_path (a server-side value from Warden options), and with Devise's own store_location_for mechanism, which sanitizes URLs via extract_path_from_location to strip external hosts and schemes. The vulnerability is classified as CWE-601 (Open Redirect) and occurs because the attacker-controllable Referer header is passed directly to Rails' redirect_to helper without path extraction or validation. Rails' global config.action_controller.action_on_open_redirect = :raise setting does not protect against this because Devise::FailureApp is an ActionController::Metal app with its own isolated configuration context.

RemediationAI

Vendor-released patch: Devise 5.0.4. Users must upgrade immediately by updating the Devise gem to version 5.0.4 or later in their Gemfile and running bundle update devise. If immediate upgrade is not feasible, apply the same code changes from the patch commit as a monkey-patch in a Rails initializer (modifying Devise::FailureApp#redirect_url and Devise::Controllers::StoreLocation#extract_path_from_location to strip external hosts from referrer-based redirects using the same extract_path_from_location mechanism applied to GET timeouts). The monkey-patch must be removed after upgrading to the patched version. No workarounds exist beyond these patching approaches; disabling the Timeoutable module entirely would prevent session expiration handling and degrade user experience. See GitHub advisory GHSA-jp94-3292-c3xv for patch details.

CVE-2017-1000117 HIGH POC
8.8 Oct 05

A malicious third-party can give a crafted "ssh://..." URL to an unsuspecting victim, and an attempt to visit the URL ca

CVE-2024-52875 HIGH POC
8.8 Jan 31

GFI Kerio Control versions 9.2.5 through 9.4.5 contain an HTTP response splitting vulnerability in the dest parameter of

CVE-2016-5385 HIGH POC
8.1 Jul 19

PHP through 7.0.8 does not attempt to address RFC 3875 section 4.1.18 namespace conflicts and therefore does not protect

CVE-2013-2248 MEDIUM POC
5.8 Jul 20

Multiple open redirect vulnerabilities in Apache Struts 2.0.0 through 2.3.15 allow remote attackers to redirect users to

CVE-2012-6499 MEDIUM POC
5.8 Jan 12

Open redirect vulnerability in age-verification.php in the Age Verification plugin 0.4 and earlier for WordPress allows

CVE-2015-2863 MEDIUM POC
4.3 Jul 20

Open redirect vulnerability in Kaseya Virtual System Administrator (VSA) 7.x before 7.0.0.29, 8.x before 8.0.0.18, 9.0 b

CVE-2017-3528 MEDIUM POC
5.4 Apr 24

Vulnerability in the Oracle Applications Framework component of Oracle E-Business Suite (subcomponent: Popup windows (li

CVE-2012-0518 MEDIUM
4.7 Oct 16

Unspecified vulnerability in the Oracle Application Server Single Sign-On component in Oracle Fusion Middleware 10.1.4.3

CVE-2024-21641 MEDIUM POC
6.5 Jan 05

Flarum is open source discussion platform software. Rated medium severity (CVSS 6.5), this vulnerability is remotely exp

CVE-2015-5354 MEDIUM POC
5.8 Jul 01

Open redirect vulnerability in Novius OS 5.0.1 (Elche) allows remote attackers to redirect users to arbitrary web sites

CVE-2015-5461 MEDIUM POC
6.4 Jul 08

Open redirect vulnerability in the Redirect function in stageshow_redirect.php in the StageShow plugin before 5.0.9 for

CVE-2024-22891 CRITICAL POC
9.8 Mar 01

Nteract v.0.28.0 was discovered to contain a remote code execution (RCE) vulnerability via the Markdown link. Rated crit

Share

CVE-2026-40295 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy