volatiletech / authboss

The boss of http auth.
MIT License
3.83k stars 207 forks source link

docs for verifier and selector strings? #201

Open jmhodges opened 5 years ago

jmhodges commented 5 years ago

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 length

I 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!

aarondl commented 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?

jmhodges commented 5 years ago

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).

aarondl commented 5 years ago

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.