OK, I don't think we're going to agree on all the points here, and this thread 
is getting really long. Let me try to summarise and see if there is a way 
forward.

The attack:
In the case of a CSRF attack against the auth code flow, detected via the 
"state" parameter, the auth code remains unused and valid. If an attacker can 
observe that auth code then they can use it themselves - they can control the 
state and PKCE in the CSRF attack, so those are not sufficient countermeasures. 
(CSRF attack here basically just means getting the user to click on a link, as 
the authorization endpoint allows cross-origin requests by design).

The main risks that the code might be exposed are:

R1. In logs on the server or any intermediary, where attacker has 
(near-)real-time access to the logs
R2. If the client doesn't scrub the URL after the error and the user then 
subsequently copy+pastes it to the attacker
R3. Referer/window.referrer leakage if the client is explicitly opting in to 
this (i.e., explicitly downgrading the Referrer-Policy - seems unlikely to me).
R4. Third-party scripts (eg analytics) on the callback page. (Not a recommended 
practice, but probably does happen).

The proposed solutions are:

S1. Use response_mode=fragment
 * Addresses R1 (fragment is not sent to server) and R3 (fragment is not 
included in Referer)
 * Doesn't address R2, in fact may make it worse (need to explicitly include a 
new fragment in a redirect to get rid of it - see 
https://www.ietf.org/rfc/rfc9700.html#name-redirect-uri-validation-atta)
 * Partially addresses R4 in that analytics providers don't store the fragment 
by default.
 * Requires client-side Javascript.

S2. Use response_mode=form-post
 * Addresses R1 (servers normally don't log POST body) and R3 (post data not 
included in Referer)
 * Addresses R2 as data is not in the URL at all, and not visible to the user.
 * Addresses R4 too, as analytics scripts also will not collect POST body 
either.
 * Requires client-side Javascript and SameSite=none cookies (if storing the 
state in a cookie, as is common).

(S1 and S2 are both vulnerable to downgrade attacks as the attacker can change 
it to response_mode=query - would need AS to actively block query response).

S3. Ensure auth code is invalidated in case of detected CSRF.
S3a: Client carries out exchange as normal but then revokes the tokens 
immediately (eg via token revocation endpoint, if supported, or maybe just by 
replaying the auth code itself).
S3b: Client uses PKCE and relies on the AS revoking the auth code in case of 
PKCE verifier mismatch. Requires AS to enforce PKCE, otherwise downgrade 
possible again.
* Addresses all risks by explicitly ensuring code/tokens are invalidated in 
case of CSRF.
* Requires change of client behaviour.
* May not actually work if AS doesn't implement revocation properly/enforce 
PKCE etc.

S4. Accept the risk, maybe tighten up wording to clarify the risks: eg sanitise 
logs, use short auth code lifetimes, always scrub code from URL even in error 
cases.
* Relies on existing countermeasures and assume short lifespan of code is 
adequate protection for the level of risk.
* Do the people who'd need to implement these countermeasures (eg web 
server/proxy admins) read security considerations for new OAuth specs? Probably 
not...

I think you have convinced me that S4 is probably not sufficient. I'm not 
convinced that S1 or S2 are good solutions, although I could maybe get on board 
for S2. S3 is probably the best technical solution, ensuring the code is 
invalidated. However, it seems like a lot of changes across the ecosystem would 
be needed, which does seem a lot given the (IMO) low risk of this ever being 
exploited.

Are there other alternatives? PAR (with client auth) would prevent the CSRF 
attack (again, if enforced by the AS), and I think JAR would too - i.e, 
preventing the CSRF by strongly authenticating auth requests. 

Best wishes,

Neil



_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to