Incorrect nonce processing in API
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Launchpad itself |
Fix Released
|
High
|
Gary Poster |
Bug Description
Using lplib in a long-running script that made tens of thousands of requests I was occasionally seeing 401-Unauthorized errors that are actually shown to be "Invalid nonce/timestamp" errors as shown below[1].
Reviewing the code in db/oath.py for ensureNonce vs the OAuth spec[2] it seems our implementation is exactly backwards. Rather than require nonce uniqueness only for the period of a given timestamp (1 second), our implementation allows nonce reuse for a period of [t-60, t+60] seconds for any timestamp t and then raises an error if the nonce is used again outside of this window. As described in the spec, re-using a nonce with different timestamps should be allowed, not an error condition.
At the top of db/oath.py there is a rationale given for the use of this expanded window but the justification is not strong. It would be better to follow the spec strictly until the need to deviate is demonstrated and well understood.
[1] https:/
[2] http://
description: | updated |
Changed in launchpad: | |
importance: | Undecided → High |
status: | Confirmed → Triaged |
description: | updated |
Changed in launchpad-foundations: | |
assignee: | nobody → flacoste |
status: | Triaged → In Progress |
Changed in launchpad-foundations: | |
status: | Triaged → In Progress |
IIRC, ensureNonce() was implemented this way for the use case described in db/oauth.py and things like http:// groups. google. com/group/ oauth/msg/ 387fdafcf0be322 a, yet still preventing replay attacks. But now I have the feeling these are two conflicting use cases, so ensureNonce() won't actually prevent replay attacks if they're made less than 60 seconds after the original request, no?
Anyway, regardless of what we decide about ensureNonce(), we must start deleting nonces older than a given number of hours/days, to avoid the clashes we're seeing.