Skip to content

Commit 7512e1a

Browse files
jasnowRubySec CI
authored andcommitted
Updated advisory posts against rubysec/ruby-advisory-db@b75f47d
1 parent 8373460 commit 7512e1a

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
---
2+
layout: advisory
3+
title: 'CVE-2026-40295 (devise): Devise has an Open Redirect via Unvalidated `request.referrer`
4+
in Timeoutable Session Timeout Handler'
5+
comments: false
6+
categories:
7+
- devise
8+
advisory:
9+
gem: devise
10+
cve: 2026-40295
11+
ghsa: jp94-3292-c3xv
12+
url: https://github.com/heartcombo/devise/security/advisories/GHSA-jp94-3292-c3xv
13+
title: Devise has an Open Redirect via Unvalidated `request.referrer` in Timeoutable
14+
Session Timeout Handler
15+
date: 2026-05-08
16+
description: |-
17+
## Summary
18+
19+
When the `Timeoutable` module is enabled in Devise, the
20+
`FailureApp#redirect_url` method returns `request.referrer` — the
21+
HTTP `Referer` header, which is attacker-controllable — without
22+
validation for any non-GET request that results in a session timeout.
23+
An attacker who hosts a page with an auto-submitting cross-origin
24+
form can cause a victim with an expired Devise session to be
25+
redirected to an arbitrary external URL. This contrasts with the
26+
GET timeout path (which uses server-side `attempted_path`) and
27+
Devise's own `store_location_for` mechanism (which strips external
28+
hosts via `extract_path_from_location`), both of which are protected;
29+
only the non-GET timeout redirect path is unprotected.
30+
31+
## Details
32+
33+
The vulnerable code is in `lib/devise/failure_app.rb`:
34+
35+
```ruby
36+
def redirect_url
37+
if warden_message == :timeout
38+
flash[:timedout] = true if is_flashing_format?
39+
40+
path = if request.get?
41+
attempted_path # safe: server-side value from warden options
42+
else
43+
request.referrer # UNSAFE: HTTP Referer header, attacker-controlled
44+
end
45+
46+
path || scope_url
47+
else
48+
scope_url
49+
end
50+
end
51+
```
52+
53+
This is passed directly to `redirect_to`:
54+
55+
```ruby
56+
def redirect
57+
store_location!
58+
# ...
59+
redirect_to redirect_url # redirect_url may be an external attacker URL
60+
end
61+
```
62+
63+
The GET timeout path uses `attempted_path`, which is set server-side
64+
by Warden and cannot be influenced by the client. The `store_location!`
65+
method also only runs for GET requests, so no session-based protection
66+
is applied on POST timeouts.
67+
68+
By contrast, Devise's `store_location_for` method (used elsewhere)
69+
correctly sanitizes URLs via `extract_path_from_location`, which
70+
strips the scheme and host.
71+
72+
## Impact
73+
74+
- Victims with expired sessions who click any attacker-crafted link
75+
or visit an attacker page with an auto-submitting form are redirected
76+
to an arbitrary external URL.
77+
- The redirect happens transparently via a trusted domain (the target
78+
app's domain), bypassing browser phishing warnings.
79+
- An attacker can redirect victims to a fake login page to harvest
80+
credentials (phishing), or to malicious download sites.
81+
82+
_Note_: Rails' built-in open-redirect protection does not mitigate
83+
this issue. `Devise::FailureApp` is an `ActionController::Metal`
84+
app with its own isolated copy of the relevant redirect configuration,
85+
so `config.action_controller.action_on_open_redirect = :raise` (and
86+
the older `raise_on_open_redirects` setting) do not reach it.
87+
88+
## Patches
89+
90+
This is patched in Devise v5.0.4. Users should upgrade as soon as possible.
91+
92+
## Workaround
93+
94+
None beyond upgrading. If an upgrade is not immediately possible, the
95+
same changes from the patch commit can be applied as a monkey-patch
96+
in a Rails initializer (`Devise::FailureApp#redirect_url` and
97+
`Devise::Controllers::StoreLocation#extract_path_from_location`).
98+
Remove the monkey-patch after upgrading.
99+
cvss_v3: 6.1
100+
patched_versions:
101+
- ">= 5.0.4"
102+
related:
103+
url:
104+
- https://www.cve.org/CVERecord?id=CVE-2026-40295
105+
- https://github.com/heartcombo/devise/releases/tag/v5.0.4
106+
- https://github.com/heartcombo/devise/blob/v5.0.4/CHANGELOG.md#504---2026-05-08
107+
- https://github.com/heartcombo/devise/commit/9ea459de9aec5f1217ad738c58e0d23fb9f5beaa
108+
- https://github.com/heartcombo/devise/commit/025fe2124f9928766fc46520e999633b598d0360
109+
- https://github.com/heartcombo/devise/security/advisories/GHSA-jp94-3292-c3xv
110+
- https://github.com/advisories/GHSA-jp94-3292-c3xv
111+
---

0 commit comments

Comments
 (0)