CIBA response parameters in PSD2 TPP use-cases

Issue #686 new
Jacob Ideskog created an issue

There are big changes rolling out in the Swedish BankID system. These are meant to prevent certain phishing attacks that are more and more common. This affects existing TPP implementations out there that use CIBA with BankID to follow the decoupled flow in PSD2.

How it used to work.

TPP (mobile apps) use CIBA to obtain tokens.

  1. During the authorization/authentication request the TPP sends the user identifier to the OP
  2. The OP starts an authentication session with BankID and obtains some session identifier it keeps
  3. The TPP receives the auth_req_id from the OP and keeps it while opening the BankID app on the same device
  4. The BankID app checks with BankID for ongoing sessions and finds one
  5. The user authenticates and is redirected back to the calling app (usually)
  6. The TPP app polls the token endpoint and once the bankid session is complete it receives the token

This is obviously very phishable as an authentication session can be created by anyone to trick the user

The update that is being rolled out prevents this (a bit) by not allowing authentication sessions to be opened without some sort of token communicated to the BankID App. There are two ways to send this token:

  1. If on same device: Pass a start-token when opening the BankID app
  2. If on different device, open the BankID app and read a QR code that contains the token

For the flow described for the TPPs in the beginning, which was a same device flow, we now have the following updates:

  1. During the authorization/authentication request the TPP sends the user identifier to the OP
  2. The OP starts an authentication session with BankID and obtains some session identifier it keeps and a start-token
  3. The TPP receives the auth_req_id from the OP but also needs the start-token to be able to start the BankID app,
  4. The BankID app checks with BankID for ongoing sessions and presents the start-token
  5. The user authenticates and is redirected back to the calling app (usually)
  6. The TPP app polls the token endpoint and once the bankid session is complete it receives the token

I think this pattern and similar patterns will surface in more regions as phishing is a growing problem. Other eID systems will likely stricten up their implementations if they can.

Current TPP implementations will not accept radical changes to their integrations (like moving to a redirect flow), so different solutions are emerging, all of them bending or breaking the standard to various degrees.

Note: In this BankID case the start-token is passed once, but it could of course be possible that it is short lived and new ones needs to be passed to the TPP.

The options I’ve seen so far are:

  • Using a different endpoint that the client knows about to get these tokens
  • Cramming the tokens in the error_description
  • Adding additional parameters to the token or authorization response

It would be helpful if the FAPI group could recommend an acceptable pattern when using CIBA and needing to communicate further information to the client about the authentication process.

Adding additional parameters in the response from the authorization call seems acceptable, since it states that the client should ignore parameters in the response that it doesn’t understand. However in the case of rotating tokens that does not suffice.

Adding additional parameters in the token endpoint response should be allowed according to RFC 6749 as far as I can understand, and if so, should it be together with authorization_pending or with some other error response?

Happy to hear some inputs on this.

/Jacob

Comments (17)

  1. Joseph Heenan

    Is this a three party flow - there’s a TPP, an OP and BankID? If you have any diagrams please that would help me understand what’s going on. I don’t think I’m following how the QR code prevents pishing in the cross device case.

  2. Bjorn Hjelm

    There was a diagram presented during the introduction of this issue on the last FAPI call. Maybe adding this diagram to the issue would help.

  3. Jacob Ideskog reporter

    Yes, it’s a three party flow. BankID does not support CIBA so the OP is in between.

    As discussed in the meeting, I think this is a broader issue than just BankID, that there is a need for guidance for these flows.

    Here is the diagram presented, it is a bit simplified to highlight the important parts.

    Steps 7-8 in the diagram can of course happen many times after step 4 has taken place, it is of no significance that I put them with the last numbers.

    However, if a start token were needed to be rotated for some reason (in other cases not this case) then step 7 is a candidate to update the client with this information.

  4. Dave Tonge

    My perspective is that separate from this request, there is a use case for the AS to communicate to the Client some information about how the authentication will take place

    I would be in favour of adding an opaque parameter to the spec that the AS can send back to the client in the Authentication Request Acknowledgement. My suggestion is that the parameter is called something like auth_context and is completely opaque to the standard, but we give an example of how it could be used

  5. Marko Milić

    Cross-Device Flows: Security Best Current Practice

    5. Cross-Device Protocols and Standards

    Cross-device protocols SHOULD not be used for same-device scenarios.
    If the Consumption Device and Authorization Device are the same
    device, protocols like OpenID Connect Core [OpenID.Core] and OAuth
    2.0 Authorization Code Grant as defined in [RFC6749] are more
    appropriate.  If a protocol supports both same-device and cross-
    device modes (e.g., [OpenID.SIOPV2]), the cross-device mode SHOULD
    not be used for same-device scenarios.  If an implementor decides to
    use a cross-device protocol or a protocol with a cross-device mode in
    a same-device scenario, the mitigations recommended in this document
    SHOULD be implemented to reduce the risks that the unauthenticated
    channel is exploited.
    

  6. Joseph Heenan

    So as I understand this flow the key reason it came into existence was to avoid a TPP app → Bank App → BankID app flow; it instead allows a direct TPP app → BankID app flow.

    The proposed addition of the autostart token (whilst I believe it improves things) I think does not give as good a security as a TPP app → Bank App → BankID app flow would. I think it would definitely be interesting to see if we can get the standard authorization code flow to work for a direct TPP app → BankID app redirect, however I don’t currently see how it would be possible without some custom extensions at the start of the flow (to get an authorization endpoint url with a request object signed by the bank) and at the end to deal with directing back from bankid to the tpp app and then the tpp app passing the authorization code back to the bank…

  7. Marko Milić

    Let’s try to recap the essence of the reported issue. Correct me if I am wrong @Jacob Ideskog
    Pain point at Swedish BankID system: An authentication session can be created by anyone to trick the user
    Resolution at Swedish BankID system: The update that is being rolled out prevents this (a bit) by not allowing authentication sessions to be opened without some sort of token communicated to the BankID App. There are two ways to send this token:

    1. If on same device: Pass a start-token when opening the BankID app
    2. If on different device, open the BankID app and read a QR code that contains the token

    IMHO any direct communication between Consumption Device (TPP Mobile App) and Authorization Device (BankID Mobile App) is going to undermine security designed by the CIBA flow. In other words we are helping an attacker to link CD and AD. Only an Authorization server should have that information.

    Possible resolution according to the CIBA spec
    CIBA supports the optional use of "user codes" as a mechanism to prevent unsolicited authentication requests from appearing on a user's authentication device.
    I just drop below some explanations I found in the spec which are related to this topic :

    • A secret code, such as a password or pin, that is known only to the user but verifiable by the OP. The code is used to authorize sending an authentication request to the user's authentication device.
    • The Client MUST NOT store the user code, but should rather request it from the user for each CIBA flow.
    • Registering a user code for a user is not in the scope of this specification. Examples include a facility provided by the authentication device or another service provided by the OP. OPs should provide a method for the user to change the user code.

    So this could raise the bar for any potential attackers in case of a phishing attack.

    And please note that only Consumption Device (TPP Mobile App) and OP are affected in case that authorization request parameter user_code is suitable regarding the update at Swedish BankID system

  8. Jacob Ideskog reporter

    Marco, I think your assessment of the problem is correct. I’d like to point out again that I don’t believe this is a BankID specific issue, many authentication systems behave like this and will have to strengthen their security.

    I don’t agree that providing an opaque to the TPP (client) would necessarily make it able to couple the authentication in a way that it shouldn’t be able to. The type of authentication taking place is often well known, either by docs, or by the structure of the username etc. The user code doesn’t add a whole lot of security to a scenario like this, since the attacker is in control of the code and can convince the user to enter it. In this particular case it’s not possible as the eID system is putting their own mitigations in place, CIBA is not in play for them.

    But lets talk about coupling instead. I think there’s a problem that CIBA is trying to be so decoupled, when in fact often coupling can exist and be beneficial. Proof of presence is the strongest defense against phishing of authentication sessions there is, but it is hard to achieve in a browser (only FIDO can do it properly) and impossible to do with CIBA.

    Example: Say that I build a non browser app, that I run in a kiosk. Take the ATM machine as an example. Say that I don’t have my credit card, but can authenticate using an eID. CIBA would be a good protocol to use since it’s a non browser based application with a limited user interface. If this ATM application had bluetooth capabilities it could start a bluetooth session against the device as a second channel to prove presence. I.e. It starts CIBA, then proves presence. However, in order to do so, it needs to challenge the device over bluetooth, but that challenge cannot be communicated using the CIBA protocol. It would be equivalent to the auto-start token above, but for a different purpose. Again, an opque to the OP that the OP would provide but that the authenticating application or client would need to use.

  9. Jacob Ideskog reporter

    From the CIBA specification section 6, use-cases, I think the ATM case above matches pretty well.

    1. A bank teller wants to authenticate a customer in a bank branch - using CIBA for authentication in a face-to-face scenario.
    2. A user wants to use their smartphone to authorize a payment they are making at a point of sale terminal.

    In both of those, to avoid MFA bombing, the user code is on option, but the stronger option would be to be able to respond with opaques that the client could use to initiate presence checks

  10. Marko Milić

    Maybe the below paragraph at the section 7.1.2. User Code can be related to the coupling aforementioned by @Jacob Ideskog

    Typically clients that establish a security context with the user prior to sending a CIBA request should be allowed without the User Code mechanism (e.g. web applications that use CIBA for step-up authentication or call center applications where a caller ID is used to identify the user). In addition, clients who don't use static user identifiers as login hints should be allowed without requiring the User Code mechanism.

    According to the CIBA’s paragraph above it is acceptable to establish a security context with the user prior to sending a CIBA request. So I do not see any obstacle that Autostart Token is communicated between TPP app and BankID app. Just wondering can it be done in next way

    • TPP App → BankID App communication, out-of-scope of CIBA i.e. implementation details
    • TPP app → Bank App → BankID communication , affects CIBA spec so maybe we can use binding_message as a value carrier in case of Autostart Token

  11. Marko Milić

    TPP app → Bank App → BankID is a typo mistake I actually mean

    TPP app → OP → BankID → BankID App communication , affects CIBA spec so maybe we can use binding_message as a value carrier in case of Autostart Token

  12. Jacob Ideskog reporter

    On the user code, it is created by the TPP, so it is not a challenge from the authentication mechanism, but yes, it tries to achieve some coupling. But in the cases I mention, and the ATM case in particular, a challenge from the server, that can be used to verify presence will be required. Letting the TPP create that sounds like a bad idea, plus in that case it’s a code for the user to enter, not a programmatic challenge that can utilize other protocols such as BLE.

    The change to TPP → OP → BankID → BankID App (which could be simplified to TPP → OP → BankID App) is not acceptable in this scenario, because the bank can not require a worse user experience for users using TPP apps than using their own app according to PSD2. So jumping the the browser in this case is not an option.

  13. Jacob Ideskog reporter

    The binding_message is a human readable message to be presented to the user, misusing that sounds like a bigger problem than advising the OP to return another parameter for coupling.

  14. Marko Milić

    Maybe I’m wrong but I understood that according to this paragraph at the section 7.1.2. User Code user code is created at OP and you can establish a mechanism at an authentication device which can invalidate/change user code at OP side at any time.

    Registering a user code for a user is not in the scope of this specification. Examples include a facility provided by the authentication device or another service provided by the OP. OPs should provide a method for the user to change the user code.

  15. Log in to comment