Transaction Authorization Cheat Sheet
Last revision (mm/dd/yy): 09/11/2017
Purpose and audience
The Purpose of this cheat sheet is to provide guidelines on how to securely implement transaction authorization to protect it from being bypassed. These guidelines can be used by:
Some applications use a second factor to check whether an authorized user is performing sensitive operations. A common example is wire transfer authorization, typically used in online or mobile banking applications. For the purpose of this document we will call that process: “transaction authorization”.
Usage scenarios are not only limited to financial systems. For example: an e-mail with a secret code or a link with some kind of token to unlock a user account is also a special case of transaction authorization. A user authorizes the operation of account unlocking by using a second factor (a unique code sent to his email address). Transaction authorization can be implemented using various methods, e.g.:
Some of these can be implemented on a physical device or in a mobile application.
Transaction authorization is implemented in order to protect for unauthorized wire transfers as a result of attacks using malware, phishing, password or session hijacking, CSRF, XSS, etc.. Unfortunately, as with any piece of code, this protection can be improperly implemented and as a result it might be possible to bypass this safeguard.
1.0 Functional Guidelines
User’s computers cannot be trusted due to malware threats. Hence a method that prevents a user from identifying transaction on an external device cannot be considered as secure. Transaction data should be presented and acknowledged using an external authorization component.
Such a transaction authorization components should be build using the “What You See Is What You Sign” principle. When a user authorizes a transaction he needs to know what he is authorizing. Based on this principle, an authorization method must permit a user to identify and acknowledge the data which are significant to a given transaction. For example, in the case of a wire transfer: the target account and amount.
The decision about which transaction data can be considered as significant should be chosen based on:
For example when an SMS message is used to send significant transaction data, it is possible to send the target account, amount and type of transfer. However, for an unconnected CAP reader it is perceived to be inconvenient for a user to enter these data. In such cases, entering only the most significant transaction data (e.g. partial target account number and amount) can be considered sufficient.
In general, significant transaction data should always be presented as an inherent part of the transaction authorization process. Whereas the user experience should be designed to encourage users to verify the transaction data.
If a transaction authentication process requires a user to enter transaction data into an external device, the user should be prompted for providing specific value (e.g. a target account number). Entering a value without meaningful prompt could be easily abused by malware using social engineering techniques as described in the example in paragraph 1.4. Also, for more detailed discussion of input overloading problems, see 2.
When a user is allowed to change authorization token by using the application interface, the operation should be authorized by using his current authorization credentials (as is the case with password change procedure). For example: when a user changes a phone number for SMS codes an authorization SMS code should be sent to the current phone number.
Some applications allow a user to chose between multiple methods of transaction authorization. In such cases, the user should authorize the change in authorization method using his current authorization method. Otherwise, malware may change the authorization method to the most vulnerable method.
Additionally, the application should inform the user about the potential dangers associated to the selected authorization method.
Malware can trick users in authorizing fraudulent operations, when an application requires a user to perform the same actions for authentication as for transaction authorization. Consider the following example:
In the abovementioned scenario, the same method was used to authenticate the user and to authorize the transaction. Malware can abuse this behaviour to extract transaction authorization credentials without the user’s knowledge. Social engineering methods can be used despite utilized authentication and operation authorization methods but the application shouldn’t simplify such attack scenarios.
Safeguards should allow the user to easily distinguish authentication from transaction authorization. This could be achieved by:
Some applications are asking for transaction authorization credentials only once, e.g. static password, code sent through SMS, token response. Afterwards a user is able to authorize any transaction during the whole user’s session or at least he has to reuse the same credentials each time he needs to authorize a transaction. Such behavior is not sufficient to prevent malware attacks because malware will sniff such credentials and use them to authorize any transaction without the user’s knowledge.
2. Non-functional guidelines
2.1 Authorization should be performed and enforced server-side
As for all other security controls transaction authorization should be enforced server-side. By no means it should be possible to influence the authorization result by altering data which flows from a client to a server, e.g. by:
To achieve this, security programming best practices should be applied, such as:
To avoid tampering, additional safeguards should be considered. For example by cryptographically protecting the data for confidentiality and integrity and while decrypting and verifying the data server side.
2.2 Authorization method should be enforced server side
When multiple transaction authorization methods are available to the user. The server should enforce the use of the current authorization method chosen by the user in the application settings or enforced by application policies. It should be impossible to change an authorization method by manipulating the parameters provided from the client. Otherwise, malware can downgrade an authorization method to a less or even the least secure authorization method.
This is especially important when an application is developed to add a new, more secure authorization method. It is not very rare,that a new authorization method is built on top of an old code base. As a result, when a client is sending parameters using the old method, the transaction may be authorized, despite the fact that the user has already switched to a new method.
2.3 Transaction verification data should be generated server-side
When significant transaction data are transmitted programmatically to an authorization component, extra care should be put into denying client modifications on the transaction data at authorization. Significant transaction data that has to be verified by the user, should be generated and stored on a server, then passed to an authorization component without any possibility of tampering by the client.
A common anti pattern is to collect significant transaction data client-side and pass it to the server. In such cases, malware can manipulate these data and as a result, show faked transaction data in an authorization component.
When transaction authorization credentials are sent to the server for verification, an application has to prevent brute-forcing. The transaction authorization process must be restarted after number of failed authorization attempts. In addition other anti brute-forcing and anti-automation techniques should be considered to prevent an attacker from automating his attacks,see OWASP Authentication Cheat Sheet.
2.5 Application should control which transaction state transitions are allowed
Transaction authorization is usually performed in multiple steps, e.g.:
An application should process such business logic flow in sequential step order and preventing a user from performing these steps out of order or in even skipping any of these steps (see OWASP ASVS requirement 15.1).
This should protect against attack techniques such as:
2.6 Transaction data should be protected against modification
The transaction authorization process should protect against attack scenarios that modify transaction data after the initial entry by the user. For example, a bad implementation of a transaction authorization process may allow the following attacks (for reference, see steps of transaction authorization described in paragraph 2.5):
The protection against modification could be implemented using various techniques depending on the framework used, but one or more of the following should be present:
2.7 Confidentiality of the transaction data should be protected during any client / server communications
The transaction authorization process should protect the privacy of transaction data being presented to the user to authorize i.e. at section 2.5, steps 2 and 4.
The result of the transaction entry and the authorization process described in paragraph 2.5 is the transaction execution. Just before the transaction is executed there should be a final control gate which verifies whether the transaction was properly authorized by the user. Such control, tied to execution, should prevent attacks such as:
2.9 Authorization credentials should be valid only by limited period of time
In some malware attacks scenarios, authorization credentials entered by the user is passed to malware command and control server (C&C) and then used from an attacker-controlled machine. Such a process is often performed manually by an attacker. To make such attacks difficult, the server should allow authorizing the transaction only in a limited time window between generating of challenge or OTP and the transaction authorization. Additionally, such safeguard will also aid in preventing resource exhaustion attacks. The time window should be carefully selected to not disrupt normal users’ behavior.
2.10 Authorization credentials should be unique for every operation
To prevent all sorts of replay attacks, authorization credentials should be unique for every operation. It could be achieved using different methods depending on the applied transaction authorization mechanism. For example: using a timestamp, a sequence number or a random value in signed transaction data or as a part of a challenge.
We identify other issues that should be taken into consideration while implementing transaction authorization. However we deem to be beyond the scope of this cheat sheet:
Authors and Primary Editors
Following persons helped by reviewing and providing valuable feedback to this work:
References and future reading
References and future reading: