Bearer token on client notification

Issue #179 resolved
James Manger created an issue

Client Initiated Backchannel Authentication Flow (CIBA) in Ping or Push modes involves an OpenId Provider POSTing to a client-registered address (backchannel_client_notification_endpoint) with a client-supplied Bearer token (client_notification_token).

How safe is this?

If a malicious client registers a web address internal to the OP it might trick the OP into calling an internal API. This is a common risk to callback scenarios, and is sort of covered in the Security Considerations that says “the OP SHOULD ensure that the "backchannel_client_notification_endpoint" configured at registration time is in the administrative authority of the Client”. Though I’m not sure how easy it is to achieve this (you presumably have to check the IP addresses the endpoint resolves to at runtime, as opposed to just a registration-time check).

Using a client-supplied Bearer token seems to make this worse. Now a malicious client might trick the OP into calling APIs that require authentication.

Getting an access token from party A to use when calling party B is almost standard OAuth. But it is usually a client accepting an access token from an OP the client has explicitly chosen to trust & register with. Whereas in the CIBA situation, the OP is accepting an access token from the client. But OPs don’t choose clients quite like clients choose OPs.

One alternative design would be to use the client_notification_token as a querystring parameter on the callback: POST <backchannel_client_notification_endpoint>?notification=<client_notification_token>. It is only moving a client-supplied value from the Authorization HTTP header to the URL, but that alone should prevent attacks on APIs requiring authentication.

Another alternative would be to require the backchannel_client_notification_endpoint to have the form https://host/.well-known/oauth-callback/label. That should make it much harder to exploit the callback for an attack, but at the cost of imposing structure on clients, and you might need rules limiting redirects to the same host.

Comments (4)

  1. Brian Campbell

    How safe is this?

    I guess I’d say that it’s safe enough so as to not warrant making breaking changes to the protocol. Noting also that https://bitbucket.org/openid/mobile/issues/146/client_notification_token-seem-redundant had some folks specifically wanting the callback to be able to be protected by a client-supplied Bearer token.

    An internal API that’s accessible from the AS but not the client would need to exist. That API needs to be RFC 6750 OAuth protected and the client needs to somehow be able to obtain an access token that would be accepted for access to the internal API. The API would need to accept a POST with JSON like either

    { "auth_req_id": "..."}
    

    or

    { "auth_req_id": "...", "access_token": "...", "token_type": "Bearer", "expires_in": ..., "id_token": "..."}
    

    that would be syntactically valid for the API and result in something happening that a malicious client would have some incentive to have happen.

    The malicious client also needs to know about this internal API and to have its backchannel_client_notification_endpoint point to said internal API. This adds some traceability and accountability to the potential attack - basically the admin of the client has to register their malicious intent with the AS, which is a further disincentive to attempt something.

    All in all, it seems quite unlikely that there’s something exploitable.

    I admittedly have some bias here because we’ve already got a CIBA implementation in product. But I don’t think we are alone in that. And I don’t think the cost/impact of making a change here is warranted.

  2. Dave Tonge

    Thanks James for raising the issue.

    I agree with Brian that the chance of a successful attack is fairly low and at this stage does not warrant a breaking change.

    I agree with your point about this phrase:

    OP SHOULD ensure that the "backchannel_client_notification_endpoint" > configured at registration time is in the administrative authority of the Client”

    Its not clear how it could be done automatically, but I think that is the point. A paranoid AS could put its own checks in place to manually review each backchannel_client_notification_endpoint

    Alternatively a paranoid AS could just not support ping/push modes, and could just support poll. With the combination of “long-polling” this can be a solution with good UX AND the same security properties as standard OIDC/OAuth flows.

  3. Log in to comment