Comments (9)
Thanks for pointing this out! I'll fix it when I have a chance.
from devise-two-factor.
Submitted to ROTP gem as mdp/rotp#44 as it's their domain to comply with HOTP and TOTP specs as defined in the RFCs.
from devise-two-factor.
I'm not sure the ROTP library is a good candidate. You have a good point that it is supposed to follow RFC (and at least document clearly where it does not). However, since you have to store somewhere the last accepted code or timestamp, ROTP would need to implement access layer to a database or other storage. That seems out of scope for such simple (purely algorithm) library.
from devise-two-factor.
@vilda I'm inclined to agree with you and the ROTP maintainer at this point. I'd hope that he'll provide extendable hooks and clear documentation in future work.
I'll probably dabble in implementing a solution in your library and submitting a PR, but I have little (read: zero) experience in working with Rails gems.
from devise-two-factor.
Would an approach like this work?
- Add a column
consumed_otp
to the devise two-factor model table. - Server, upon supplied a valid OTP, hashes a concat of the current timestep and valid OTP and compares it to the value stored in
consumed_otp
. - If there is no match, permit login and update
consumed_otp
value for the row. If there is a match, deny login as it's a "burned" OTP code for that time step.
I feel like it's acceptable because:
- The concatenation of the time step ensures the burned code applies only for that given time step
- There's no master list of N-many "burned codes" since we only need to know the one code issued for a given timestep.
- A valid OTP is inherently unique to a given user, therefore the resulting hash is unique to a given user.
from devise-two-factor.
I don't think the hashing step is necessary. Storing the timestep of the most recently successful authentication should be sufficient -- we don't care what the OTP was, we just care that a given OTP is only used once, and since each timestep has only one OTP, we can avoid needing to store the OTP entirely.
Other than that, your approach looks fine to me.
It's also important to ensure that we work with the timestep used to generate the OTP -- not the timestep associated with the request. Because of the drift period, these may not be the same.
from devise-two-factor.
I'm happy with your suggestion.
But with your approach, if you want to be anal about it, a user could theoretically login (thereby burning that timestep) disable & renable OTP, log out and try to login with a new OTP for that same timestep and getting denied, despite providing a unique OTP. Now with the default ROTP timestep interval being 30 seconds, and tinfoil's gem offering no option to override it, this becomes a very unpractical & narrow issue.
from devise-two-factor.
Ha, I hadn't thought of that!
That does sound like a valid bug, though it's enough of an edge case that I think I'd prefer sticking with the simpler implementation. If anyone raises their pitchforks in the future because of it, you can point them in my direction :P
from devise-two-factor.
Fine by me 😉
from devise-two-factor.
Related Issues (20)
- Clarification about setup with rails 6 HOT 1
- missing attribute: encrypted_otp_secret
- Remove "Rails 4" misleading sentences from readme
- NoMethodError Exception: undefined method `tr' for nil:NilClass HOT 1
- Require email verification when enabling Authenticator App type
- Generator throws exception HOT 1
- `Devise.add_module(:two_factor_authenticatable)` should be inserted on top
- calling super in the two factor strategy is problematic...
- Remove the old `otp_secret_encryption_key` in the UPGRADING.md guide
- Git tag for v4.1.0 appears to be missing HOT 2
- No changelog for 4.1.0
- `user.current_otp` code sent to user are always invalid HOT 1
- [question] mass users update?
- Not required on every login HOT 1
- Rails 7.1 on 4.x HOT 1
- Support for Rails 7.1 HOT 3
- ActiveRecord::Encryption::Errors::Decryption error on login after upgrade to Rails 7.1 defaults HOT 3
- Backup codes aren't written to the database so can't be used HOT 1
- Clarification on GHSA-chcr-x7hc-8fp8 HOT 8
- Lockbox instead of ActiveRecord encrypted attributes HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from devise-two-factor.