Honestly, DPoP[1] is pretty horrible. It is a partial re-implementation of TLS client authentication deep inside the TLS connection. What's wrong:
- No mandatory liveliness check. That means you don't know whether the proof of possession was indeed issued right now or has been pre-issued by an attacker with past access. Quoting from the spec[2]: """Malicious XSS code executed in the context of the browser-based client application is also in a position to create DPoP proofs with timestamp values in the future and exfiltrate them in conjunction with a token. These stolen artifacts can later be used together independent of the client application to access protected resources. To prevent this, servers can optionally require clients to include a server-chosen value into the proof that cannot be predicted by an attacker (nonce).""" This is a solved problem in TLS.
- The proof of possession doesn't cover much of an HTTP request, just "The HTTP method of the request to which the JWT is attached" and "The HTTP request URI [...], without query and fragment parts." It doesn't even cover the query parameters or POST body. Given rational: """The idea is sign just enough of the HTTP data to provide reasonable proof-of-possession with respect to the HTTP request. But that it be a minimal subset of the HTTP data so as to avoid the substantial difficulties inherent in attempting to normalize HTTP messages.""" In short: Because it is so damn difficult to do it on this layer. Of course, TLS covers everything in the connection.
- Validating the proofs, i.e. implementing the server side of the spec, is super complicated, see [3]. And to do it right you also need to check the uniqueness of the provided nonce see [4] which brings its own potential attack vectors. And to actually provide liveliness checks (see above) you have to implement a whole extra machinery to provide server chosen nonces see [5]. I expect several years until implementations are sufficiently bug free. Again, TLS has battle tested implementations ready.
Best of all? There is already a spec to do certificate based proof of possessions using mutual TLS! See [6]. We really should invest our time in fixing our software stack to use the latter (e.g. by adding JavaScript initiated mTLS in browsers) instead of yet another band aid in the wrong protocol layer.
- No mandatory liveliness check. That means you don't know whether the proof of possession was indeed issued right now or has been pre-issued by an attacker with past access. Quoting from the spec[2]: """Malicious XSS code executed in the context of the browser-based client application is also in a position to create DPoP proofs with timestamp values in the future and exfiltrate them in conjunction with a token. These stolen artifacts can later be used together independent of the client application to access protected resources. To prevent this, servers can optionally require clients to include a server-chosen value into the proof that cannot be predicted by an attacker (nonce).""" This is a solved problem in TLS.
- The proof of possession doesn't cover much of an HTTP request, just "The HTTP method of the request to which the JWT is attached" and "The HTTP request URI [...], without query and fragment parts." It doesn't even cover the query parameters or POST body. Given rational: """The idea is sign just enough of the HTTP data to provide reasonable proof-of-possession with respect to the HTTP request. But that it be a minimal subset of the HTTP data so as to avoid the substantial difficulties inherent in attempting to normalize HTTP messages.""" In short: Because it is so damn difficult to do it on this layer. Of course, TLS covers everything in the connection.
- Validating the proofs, i.e. implementing the server side of the spec, is super complicated, see [3]. And to do it right you also need to check the uniqueness of the provided nonce see [4] which brings its own potential attack vectors. And to actually provide liveliness checks (see above) you have to implement a whole extra machinery to provide server chosen nonces see [5]. I expect several years until implementations are sufficiently bug free. Again, TLS has battle tested implementations ready.
Best of all? There is already a spec to do certificate based proof of possessions using mutual TLS! See [6]. We really should invest our time in fixing our software stack to use the latter (e.g. by adding JavaScript initiated mTLS in browsers) instead of yet another band aid in the wrong protocol layer.
[1] https://tools.ietf.org/id/draft-ietf-oauth-dpop-08.html
[2] https://tools.ietf.org/id/draft-ietf-oauth-dpop-08.html#sect...
[3] https://tools.ietf.org/id/draft-ietf-oauth-dpop-08.html#name...
[4] https://tools.ietf.org/id/draft-ietf-oauth-dpop-08.html#name...
[5] https://tools.ietf.org/id/draft-ietf-oauth-dpop-08.html#name...
[6] https://www.rfc-editor.org/rfc/rfc8705.html