#28248 closed Bug (invalid)
Password resets are allowed for 1 day longer than PASSWORD_RESET_TIMEOUT_DAYS
Reported by: | Nick Zaccardi | Owned by: | nobody |
---|---|---|---|
Component: | contrib.auth | Version: | 2.0 |
Severity: | Release blocker | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
An improper comparison (> rather than >=) in the password reset token checking, allows password reset tokens to be used one day longer than expected.
Change History (12)
comment:1 by , 7 years ago
Has patch: | set |
---|
comment:3 by , 7 years ago
Resolution: | fixed |
---|---|
Status: | closed → new |
I believe this change is incorrect and should be reverted, according to a common sense interpretation of the setting.
The code rounds all timestamps to midnight (server time) providing a resolution of only 1 day. So if you generate a links 5 minutes before midnight and try to use it 6 minutes later, that counts as 1 day. With the current code, if you set the timeout setting to 1 day, such a link would be rejected.
In other words, new code interprets timeout of 1 day as "up to one day, could be almost zero". The old way interpreted as "at least 1 day, could be up to 2". I think the old way was better, much less likely to be an accidental usability issue. There is virtually no security concern with being too generous here (see my latest post on django-devs on related issue).
comment:4 by , 7 years ago
Severity: | Normal → Release blocker |
---|---|
Version: | 1.11 → 2.0 |
comment:7 by , 7 years ago
Resolution: | fixed → invalid |
---|
comment:8 by , 7 years ago
I think it would be great to add at least some part of Luke's comment in a code comment to prevent further reports about this issue.
follow-up: 11 comment:10 by , 7 years ago
Sorry to be a moment late to respond. I think the reversion is the correct action for the 99+% and I support that direction. In fact, the fix I originally supplied does have the rounding bug. My apologies for that, I misunderstood the way the rounding work.
I do want to explain why this doesn't meet the 1% of use cases. When I originally reported this I was working on a password reset feature in a different app (a large corporate financial application) which has very specific policies on passwords, password resets, and the validity time of both. From a contractual perspective (regardless of user experience) >24hr link would be a break in policy or worse a violation of contractual obligation to implement a <24hr link. For most up to 2 days is fine, for some, regardless of the real-life implications of the policy, it is a big deal.
All that to say, why does this get rounded in the first place? why not just use:
validity_time = now() + {{ reset_timedelta }} if validity_time < now(): // is expired
Thanks for all you folks do!
comment:11 by , 7 years ago
Replying to Nick Zaccardi:
I do want to explain why this doesn't meet the 1% of use cases. When I originally reported this I was working on a password reset feature in a different app (a large corporate financial application) which has very specific policies on passwords, password resets, and the validity time of both. From a contractual perspective (regardless of user experience) >24hr link would be a break in policy or worse a violation of contractual obligation to implement a <24hr link. For most up to 2 days is fine, for some, regardless of the real-life implications of the policy, it is a big deal.
Thanks for filling in these background details. It is unfortunate that sometimes these policies exist which actually don't apply (for reasons that I described here - https://groups.google.com/d/msg/django-developers/65iOQunvkPY/pP5mF-44AQAJ )
However, your experience is still a significant data point in favour of the feature being asked for in that thread ( https://groups.google.com/forum/#!topic/django-developers/65iOQunvkPY ), namely, supporting a timeout of less than one day. Please do feel free to jump into that thread and add your 2 cents - we have to be pragmatic about complying with these kinds of regulations.
All that to say, why does this get rounded in the first place? why not just use:
It is mainly rounded to make the timestamp shorter (we only need to store a number of days, not seconds), which has an impact on the length of URL generated. That may sound like a dubious argument, but that was the initial rationale I believe! With some email clients that like to truncate URLs etc., it can make a difference. Maybe things are better these days...
PR