On September 14th the final deadline of complying with the new Payment Service Directive PSD2 will be reached. Among other things, this directive will bring quite a few technical challenges for credit institutions. These include new requirements on two-factor authentication and API access for third parties. In this blog post we will give a short overview of what this means for banks from a security perspective and outline a few of the security-related issues based on what we have been observing during recent assessments of such APIs.
This post will concentrate on the mandatory account access for Third Party Providers (TPPs) banks have to provide. A TPP can be either an Account Information Service (AIS) or Payment Initiation Service (PIS). An AIS can be authorized to obtain account information from a user’s bank account. This enables service providers to, for example, create applications that show an overview over multiple bank accounts and their balances. A PIS on the other hand can initiate transactions with a bank and receive feedback on the success of a transaction. German readers might know “Sofortüberweisung” which provides something like a PIS. When paying for an expense on the internet, e.g. in an online shop, customers can log into Sofortüberweisung using their banking credentials. The service will initiate the bank transfer and on success notify the online shop about the transfer. The shop can then process the purchase without waiting for the money to arrive on their account. There are of course other applications of a PIS.
Licenses and Certificates
What all of these TPPs have in common is that they need to be authorized for offering their services and communicating with credit institutions. This consists of two steps. First, they need to get a license to be a TPP by a national banking authority (National Competent Authority – NCA). For Germany this is the “BaFin”. For other countries you can find the list here. Then, after obtaining this license, the provider needs to request a Qualified Website Authentication Certificate (QWAC) by a Qualified Trust Service Provider. This is used to identify the service and establish a mutually authenticated TLS connection between the bank and the provider. As soon as a provider has a valid certificate, they can use the API of any bank in the EU. This API therefore certainly is a critical part of a bank’s infrastructure. In addition to the QWAC certificate, PSD2 also defines the usage of sealing certificates for signing data. As the usage of a sealing certificate is optional it will not be covered here.
However, PSD2 only defines the presence of such an API, it does not get into details as to how it should be implemented, which resulted in efforts to create standardized banking APIs according to PSD2, such as OpenID’s Financial Grade API or the NextGenPSD2 Framework.
The PSD2 API is certainly a critical interface for credit institutions as it potentially exposes customer account information to all entities holding a valid QWAC certificate. In the following we will get into some of the critical aspects and how to test them.
The purpose of the certificate-based authentication is that only authorized clients are able to access the banking APIs. For this, the certificate contains several fields related to PSD2, such as the authorizing NCA’s ID or the PSP authorization number. If the API is implemented correctly, it will only accept valid QWAC certificates, that is, certificates that are properly signed by an NCA. There are a few things that should be tested with regards to the certificate-based authentication.
A proper validation of the certificate before accepting any of data contained in the certificate’s fields is important. Accepting the data of arbitrarily created certificates would allow an attacker to craft these and potentially impersonate other authorized clients. A common implementation mistake that we have observed occurs when a proxy with TLS termination is used. Often, relevant fields from the certificate are placed in headers by the proxy where the actual application server can then process these values. If the headers are not properly overwritten by the proxy, it might be possible to inject arbitrary values in these headers, which results in an outcome similar to crafted certificates. Of course, this only works if the server either accepts requests without a certificate, or the attacker is in possession of another valid certificate.
Another test should be to check whether the API accepts self-signed QWAC certificates, or certificates that are issued by an entity that is not an NCA. The reason why this is especially important to test is that many banks have had a sandboxed version of their PSD2 API running for a while now. For testing purposes users were able to request testing certificates that were accepted by the API. The production version of the API should contain a different validation logic and not accept these testing certificates.
Generally, the API should only accept requests from clients with proper NCA issued certificates. It should not respond to requests without certificates or crafted certificates. Additionally, the test should include a check with a validly issued but expired certificate. Each endpoint in the API needs to be checked for these properties. To completely cover the API, the assessment needs to include each HTTP method for each endpoint (i.e. GET and POST is not enough).
Behind the Authentication
According to the PSD2, a TPP will only get a valid PSD2 certificate if they are authorized by an NCA. However, this is not necessarily a technical restriction. From a technical perspective, it is enough to have a valid certificate to be able to use the API. Now there are ways to become the holder of a valid PSD2 certificate without being previously authorized by an NCA, such as compromising the Qualified Trust Service Provider or simply stealing a valid PSD2 certificate from another TPP. Thus it is important to properly check the API even behind the authentication. Simply trusting an authenticated client is not enough.
Clients that access one of the PSD2 interfaces should only be able to access an account of a user that has logged into their bank account. Two things should be tested here. Firstly, an authenticated user using the client should not be able to access other customers’ accounts. Secondly, and more importantly, the client should not be able to access arbitrary accounts without being authenticated by a banking customer. Usually the user authentication is realized by an access delegation protocol such as OAuth (which is what the NextGenPSD2 standard proposes).
Injection attacks in banking-related APIs are always extremely dangerous. While the impact of an injection depends on the implementation and the used technology, the parameters and sent data need to be properly tested. Typical test apply here, such as sending undesired input data, SQL comments and queries, or in case XML is used XXE payloads. A successfull XXE attack, for example, might give an attack the ability to read arbitrary files on the file system of the API server, in some cases it might even result in remote code execution. In the context of a malicious user or malicious client this poses a high risk.
Even if the authorized client is not malicious, it might be that the user using the client has malicious intents. Combined with a vulnerability behind the authentication (such as an access control issue or an injection vulnerability), the API is exposed to risk.
Thoroughly testing the PSD2 compliant APIs is crucial and what we have shown in this post is only an excerpt of what should be done to evaluate the security of the PSD2 interface. Vulnerabilities in the API implementation and in the authentication and access control mechanisms can, in the worst case, result in huge financial losses for both banking customers and the banks themselves. This makes the AIS and especially the PIS interface an extremely valuable target for attackers.