OAuth 2.0 finalized
dickhardt.org
dickhardt.org
I believe the committee had a lot of different ideas about how certain problems should be approached and instead of choosing 1 solution they either decided to keep some things open for the implementer or allowed several solutions to a problem as part of the spec.
It's mostly trivial things last I looked (comma delimited scopes instead of space delimited, `expires` instead of `expires_in`, and so on). Glancing over the final spec, seems headers are preferred now (which is almost always dumb IMO, but that's a whole separate rant) and Facebook only does query strings.
Looks as though the spec bloated a bit, though there's probably still a sane-ish kernel worth implementing in there compared to OAuth 1.0a.
It seems easier to me to keep a bearer token secret (out of server and client-side logs/history, etc.) if it doesn't go into the query string -- though certainly it's easier for developers using your API if they can explore it with just a browser.
In general though, I think the ease of development that comes from query strings trumps any supposed security gains of using headers for passing parameters.
Fundamentally, if you're worried about secrets being logged you're worried about MITM attacks (if either endpoint stores secrets insecurely, that's a whole other concern). If someone's actually managed to MITM a user, it's no harder to capture headers than query strings; so it's a mostly false sense of security. To prevent MITMs, you should just mandate HTTPS; that gives you some real improvement, not just one for the very narrow "traffic logs subsequently compromised" case (and even that assumes the log in question isn't capturing headers, which may be typical but is by no means universal).
OAuth2 does require SSL, and you're right that both params and headers are equally protected there.
My main concern with putting "secrets" in query strings is that traditionally sensitive data doesn't go in query strings -- it'd be in POST content, normally -- so both browsers and servers are less careful with that data.
Headers DO sometimes contain sensitive data (i.e., standard http auth), so there's a history there, and by default this info would be protected a bit more than GET params, I think.
I do care about the endpoints, for two reasons -- on the server side, a log accidentally containing sensitive data might contain all of the secret tokens for the service, and logs are generally not as carefully protected as, say, the database, so they might be posted for developer review or otherwise exposed.
On the client-side: if a single client is hacked, that's normally just one token exposed (whether it was being passed via header or param, probably). But if the browser simply isn't treating the token as secret data, then it gets around -- addons might send queries out to a server for various contextual features, Google may collect it (to help live search dropdowns), etc. -- it's simply not treated as carefully, so it gets out.
Of course, production uses (vs. developers wandering around) generally wouldn't even be using a browser (and I could personally make sure these params weren't in our logs), so none of this is disastrous; just issues on my mind.
1. Get a login URL. Send people here to log in.
2. Receive an auth token if the user clicked allow on the login page
3. Swap the auth token for access and renewal tokens.
Optional 4: Maybe renew if you expire.