Open jmhodges opened 5 years ago
The selector and verified were implemented because of a bug report filed via reddit actually.
The bug report was here: https://www.reddit.com/r/golang/comments/8jgn9l/authboss_v2/dz04o48 Note the link to the "split tokens" article: https://paragonie.com/blog/2017/02/split-tokens-token-based-authentication-protocols-without-side-channels
The terminology comes from there. But essentially you have a selector token that is used to look things up in the database which is vulnerable to timing attacks because it's essentially using strncmp
to ensure two strings match, but then once you've retrieved the verifier
using that, you use a constant time compare on the verifier
so that you work around that vulnerability.
The godoc in recover states:
// GenerateRecoverCreds generates pieces needed for user recovery
// selector: hash of the first half of a 64 byte value
// (to be stored in the database and used in SELECT query)
// verifier: hash of the second half of a 64 byte value
// (to be stored in database but never used in SELECT query)
// token: the user-facing base64 encoded selector+verifier
func GenerateRecoverCreds() (selector, verifier, token string, err error) {
Is there more you were looking for?
This is all wonderful context! As a user of your design, a wiki page with this information that the selector and verifier godoc bits linked to would be great. I didn't find that GenerateRecoverCreds immediately, and when I did, it still left me with questions. You've answered them with such a good comment that I think it's worth elevating to docs. Or maybe the blog post could be linked from the GenerateRecoverCreds doc and the other selector and verifier docs could mention GenerateRecoverCreds?
It might also be cool to give a good max lengths for the values so people can get their schemas right (I can never remember the math for base64).
Confirmations carry two values in the database to prevent a timing attack. The selector and the verifier, always make sure in the ConfirmingServerStorer you're searching by the selector and not the verifier.
This is what's in the README currently which is a definitive source for additional documentation that a typical user would require. The wiki is for very offshoot topics. If we were going to add length information anywhere it should document all the possible values that could be in the database so that you don't have to chase all over the godoc for it. Happy to outsource this :)
Though I'm skeptical of the utility of string sizes in databases. In postgres at least varchar
basically means that the data must be stored with a variable length anyway and so there's no difference between that and text
(https://stackoverflow.com/questions/4848964/postgresql-difference-between-text-and-varchar-character-varying). Not sure for mysql.
Hey, love the new API. Have some questions and it seemed like a good place to write a docs ticket about them.
There's mentions in the doc of "selector" and "verifier" strings, but it's not actually mentioned what they are use for, what their limits are, or how they are different from one another.
The names are a little vague and it was unclear to me what purpose they had. Were they column names ("selector" is often used in CSS, for instance, to reference a place in HTML) or column values?
For instance, it would be nice to have it written down which values are compared with
crypto/subtle.ConstantTimeCompare
and so we should make sure the strings are all the same lengthI also went to authboss-sample to look and it's not clear that it actually controls what is in the verifier strings. "How long are those strings", etc, seem like open questions when looking at the code? (I'm def not saying authboss-sample should be the authoritative place for this and would much prefer godoc!)
Thanks for reading this long question!