Skip to content

Commit 8e3a936

Browse files
jasnowRubySec CI
authored andcommitted
Updated advisory posts against rubysec/ruby-advisory-db@f9bbec6
1 parent 2aa06ef commit 8e3a936

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
layout: advisory
3+
title: 'GHSA-57hq-95w6-v4fc (devise): Confirmable "change email" race condition permits
4+
user to confirm email they have no access to'
5+
comments: false
6+
categories:
7+
- devise
8+
advisory:
9+
gem: devise
10+
ghsa: 57hq-95w6-v4fc
11+
url: https://github.com/heartcombo/devise/security/advisories/GHSA-57hq-95w6-v4fc
12+
title: Confirmable "change email" race condition permits user to confirm email they
13+
have no access to
14+
date: 2026-03-16
15+
description: |
16+
## Impact
17+
18+
A race condition in Devise's Confirmable module allows an attacker
19+
to confirm an email address they do not own. This affects any Devise
20+
application using the reconfirmable option (the default when using
21+
Confirmable with email changes).
22+
23+
By sending two concurrent email change requests, an attacker can
24+
desynchronize the confirmation_token and unconfirmed_email fields.
25+
The confirmation token is sent to an email the attacker controls,
26+
but the unconfirmed_email in the database points to a victim's
27+
email address. When the attacker uses the token, the victim's email
28+
is confirmed on the attacker's account.
29+
30+
## Patch
31+
32+
This is patched in Devise v5.0.3. Users should upgrade as soon as possible.
33+
34+
## Workaround
35+
36+
Applications can override this specific method from Devise models
37+
to force unconfirmed_email to be persisted when unchanged:
38+
(assuming your model is User)
39+
40+
```
41+
class User < ApplicationRecord
42+
protected
43+
44+
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
45+
unconfirmed_email_will_change!
46+
super
47+
end
48+
end
49+
```
50+
51+
Note: Mongoid does not seem to respect that will_change! should
52+
force the attribute to be persisted, even if it did not really
53+
change, so you might have to implement a workaround similar to
54+
Devise by setting changed_attributes["unconfirmed_email"] = nil as well.
55+
patched_versions:
56+
- ">= 5.0.3"
57+
related:
58+
url:
59+
- https://about.gitlab.com/releases/2023/01/09/security-release-gitlab-15-7-2-released
60+
- https://github.com/heartcombo/devise/pull/5784
61+
- https://github.com/heartcombo/devise/issues/5783
62+
- https://portswigger.net/research/smashing-the-state-machine
63+
- https://groups.google.com/g/heartcombo/c/ieiLJhG4EGE/m/PNlIQv54AAAJ
64+
- https://groups.google.com/g/heartcombo/c/o9mtkcfvt_g/m/SABX6rp8AgAJ
65+
- https://groups.google.com/g/heartcombo/c/XDII89RV6Ak/m/AJMOyayNAgAJ
66+
- https://groups.google.com/g/heartcombo/c/TWge7vKELhc/m/gRTrgKz4CQAJ
67+
- https://github.com/heartcombo/devise/security/advisories/GHSA-57hq-95w6-v4fc
68+
---

0 commit comments

Comments
 (0)