4 ms·
Problems I see: - Anyone with access to the secret token can now generate their own urls without fail or evidence. With a DB you need to at least insert a row
by Justsignedup 12y ago
Problems I see:
- Anyone with access to the secret token can now generate their own urls without fail or evidence. With a DB you need to at least insert a row and thus leave evidence (especially if you are auditing db activity)
- No way to individually invalidate anyone. Example: What if ONE account's db tokens were exposed. Should be able to invalidate those tokens, not ALL tokens.
- Not necessarily easier than one "expiring token" mechanism that is re-used throughout the system.
- I don't feel great about exposing all my private security checks in url parameters. Why give users clues on how I do security? I can provide that in a better, more meaningful way.
- No way to easily invalidate all tokens of specific nature. Example: If you want to invalidate all password reset tokens, all 2-factor authorization tokens, all confirm email tokens after any password reset, all systems must know of each other rather than go to the token table and set "valid" on all those tokens to "false" for everything. The hash would need to account for what change triggers this hash invalidation rather than just someone picking what to reset from a dinner menu as a separate concern.
- hvidgaard 12y ago> Anyone with access to the secret token can now generate their own urls without fail or evidence. With a DB you need to at least insert a row and thus leave evidence (especially if you are auditing db activity) And they wouldn't be valid. It's much simpler to invalidate them provided that you don't need information from the DB, than reading from the DB. > No way to individually invalidate anyone. Example: What if ONE account's db tokens were exposed. Should be able to invalidate those tokens, not ALL tokens. Of course you design it in such a way, that you can change one of the inputs, which will by definition invalidate the tokens. > Not necessarily easier than one "expiring token" mechanism that is re-used throughout the system. The point is to seperate this boilerplate logic from your core business logic. > I don't feel great about exposing all my private security checks in url parameters. Why give users clues on how I do security? I can provide that in a better, more meaningful way. Any serious security systems assume that an attacker already know 100% of the workings of the system. You should not rely on obscurity, but on your secret - in this case the crypto key. > No way to easily invalidate all tokens of specific nature. Again, if this is a requirement, then make such a global parameter an input to the token generation. It's still much simpler than doing it "the old fashioned way".
- pwf 12y ago> Of course you design it in such a way, that you can change one of the inputs, which will by definition invalidate the tokens. I was looking at using JWT to avoid a database read when authenticating a request, but in order to get some sort of variable per-user value I'd have to hit the database to get it, no? Doesn't that kind of defeat the purpose?
- hvidgaard 12y agoSaid variable could be in memory, but the point isn't to save DB reads, but to avoid saving data you don't need to. This is a technique to implement the same feature without having to store additional information in your core business logic, that is relatively useless outside of this password reset or user signup. Of course you may want to save this for BI of audit purposes, but then you can (and should) use an appropiate seperate system.
- tripzilch 12y agoNote that the title says avoiding database writes.
- vidarh 12y ago> - Anyone with access to the secret token can now generate their own urls without fail or evidence. With a DB you need to at least insert a row and thus leave evidence (especially if you are auditing db activity) Include a parameters that varies with user. And optionally something that will change over time, and that an attacker can not trivially obtain. Now the generated urls will fail unless the attacker knows both the user ids _and_ the auxiliary information. You can make that auxiliary information simple (e.g. last login time and old password hash, in the password reset example), or you can explicitly generate a value per user that is updated according to certain criteria. Call it an API key for the user account. (as for auditing, nothing stops you from logging requests; a big difference is typically that it's easier to scale non-transactional log-writes where eventual consistency is generally sufficient) > - No way to individually invalidate anyone. Example: What if ONE account's db tokens were exposed. Should be able to invalidate those tokens, not ALL tokens. See above. All you need, is to ensure the URL includes a value that can be changed per user. This could be an existing field that is re-purposed (as in the "last login time" example, or a field added explicitly for this purpose if you so choose. But it's a valid consideration. > - Not necessarily easier than one "expiring token" mechanism that is re-used throughout the system. - I don't feel great about exposing all my private security checks in url parameters. Why give users clues on how I do security? I can provide that in a better, more meaningful way. So encrypt the fields to obscure it, or make the key/values mean nothing to users. > - No way to easily invalidate all tokens of specific nature. Example: If you want to invalidate all password reset tokens, all 2-factor authorization tokens, all confirm email tokens after any password reset, all systems must know of each other rather than go to the token table and set "valid" on all those tokens to "false" for everything. The hash would need to account for what change triggers this hash invalidation rather than just someone picking what to reset from a dinner menu as a separate concern. All you need is to encode a value for the request type as part of the information that you can change when you want to invalidate that type of request. You don't need to include that information in the URL either (assuming the URL already holds other information to identify the type of request) Bump the value, and all the old urls of that type are now invalid. You don't even need to think about this in advance: Just allow the mapping to map to null/nil and in that case don't include the value when calculating the hmac. Now you can invalidate one specific type without invalidating any of the other urls that pre-date adding this mechanism. It's easy to evolve this checking if you identify additional factors you need to be able to revoke on. You can also use this mechanism to selectively enable/disable subsets of requests based on various factors (e.g. you can create urls that are only valid within office hours, if you please, by including a flag when you calculate the hmac, and change the "true" value of that flag depending on the time of day), though it quickly becomes easier to simply include the information in the URL and relying on the HMAC to determine validity of the assertion.