Search code examples
python-3.xoauth-2.0openid-connectpkce

Is Public Key encryption acceptable for protecting last leg of this OpenId Connect workflow


  • Desktop Client
  • Protected Resource Server
  • Authorization Server (Google)
  • User-Agent (Browser)

  1. The Desktop Client generates Pub/Priv key pair, and directs the user agent with webbrowser.open_new() to Protected Resource Server OAuth initiation page, which stores the Public Key in the State parameter field of the Auth_URI redirect.
  2. User-Agent successfully auths with the Authorization Server and is redirected back to Protected Resource Sever with Auth_Code and Public Key in state parameter field.
  3. Protected Resource Server exchanges Auth_Code using confidential client secret and validates id_token.
  4. If id_token is valid, (server side processing happens), it then redirects on loopback to listening Desktop Client with query parameter containing an encrypted value that is only accessible by the initiating app.

It's a very similar process to PKCE, but I'm having the Client Secret remain confidential on the sever rather than embedding it in the Desktop Client.

My concern is about a malicious 3rd party app that is able to intercept the initial OAuth_URI redirect and modify its values. Is this a mitigable threat once the device/browser is compromised? PKCE would suffer from the same issue and I've seen no explanations that mention my concern as a particular issue so I am under the assumption it is fine.


Solution

  • REDIRECT TAMPERING

    The standard protection against malicious redirect tampering is in these emerging standards:

    In high security scenarios you may need to follow profiles that mandate some of these - and some profiles may include financial-grade recommendations such as FAPI 2.0 Client Requirements, which includes PAR.

    DESKTOP APPS

    One known issue for desktop apps is that a malicious app could send the same client ID and use the same redirect URI to trigger a complete flow. I don't think you can fully protect against that, and any efforts may just be obfuscation.

    Your concern is perhaps this issue, and it is not currently solvable, since any code your app runs could also be run by a malicious app, including use of PAR / DPop or other advanced options.

    CLIENT ATTESTATION

    The behaviour you are after is client attestation, where a malicious party cannot attempt authentication without proving its identity cryptographically. Eg an iOS app can send proof of ownership of its App Store signing key.

    Mobile and web apps can achieve a reasonable amount of client attestation by owning the domain for an HTTPS based redirect URI, but these cannot be used for desktop apps. It would be good to see improved client attestation options for desktop apps some time soon.

    WHAT TO DO?

    Generally I would say keep your code based on standards that have been vetted by experts. This should mean that you use libraries in places but that your code remains simple.

    Also your desktop app will be as secure as other desktop apps without trying to solve this problem. Also, users are socialised to not run arbitrary EXEs these days, and only run proper signed apps, whose code signing certificate identifies them and chains up to an authority that has approved the app (we hope).