Logging a user in proves who they are, but it does not prove they approved a particular payment, beneficiary change or high-risk action, and attackers with a hijacked session or malware in the browser exploit exactly that gap. Transaction authorisation is the separate control that binds a user's explicit approval to the specific details of one operation, so that a changed amount, payee or parameter invalidates the approval. This guide covers the What You See Is What You Sign principle, dynamic linking under the PSD2 regulatory technical standards, the implementation rules from the OWASP Transaction Authorization Cheat Sheet, method choices from SMS codes to device signing and Secure Payment Confirmation, and how the same pattern applies when AI agents initiate transactions. It is for developers and architects of banking, payments, fintech and any application with high-value actions.
Key takeaways
- Authorise the transaction, not the session. Each sensitive operation needs its own approval credential, generated for that operation and accepted once.
- Bind approval to the data that matters. PSD2 dynamic linking requires the authentication code to be specific to the amount and payee, and any change to either invalidates it.
- Show the details on a channel malware does not control. What You See Is What You Sign only works if the confirmation display is outside the possibly compromised browser, such as a separate app, hardware device or browser-controlled dialog.
- Enforce everything server-side. The server generates the transaction data to be confirmed, controls the state machine, checks the method, and has a final gate before execution.
- Make authentication and authorisation look different. OWASP warns that if login and transaction approval use the same action, malware can trick users into "logging in again" and use the second code to approve a fraudulent transfer.
Authentication, step-up and transaction authorisation compared
| Control | What it proves | Bound to | Typical mechanism |
|---|---|---|---|
| Authentication | The user is who they claim | A session | Password plus MFA, passkey |
| Step-up authentication | The user re-proved identity at a higher assurance recently | A session or token with a fresher, stronger acr or auth_time | OAuth step-up challenge (RFC 9470), re-authentication prompt |
| Transaction authorisation | The user approved this specific operation with these details | One transaction (amount, payee, parameters) | Dynamically linked OTP, device signature over transaction data, Secure Payment Confirmation |
Step-up raises confidence in the session, but a session-level token still authorises whatever the attacker submits while it is valid. Transaction authorisation is narrower and stronger. Many systems need both: step-up before reaching a payments area, and per-transaction approval for each payment. See the OAuth Step-Up Authentication Challenge Guide for the session-level pattern.
ASVS 5.0 captures the requirement at two levels: V7.5.3 requires further authentication with at least one factor or secondary verification before highly sensitive transactions, and V4.1.5 requires per-message digital signatures for requests or transactions that are highly sensitive or traverse many systems.
What You See Is What You Sign and dynamic linking
The OWASP Transaction Authorization Cheat Sheet states the principle directly: an authorisation method must let the user identify and acknowledge the data that is significant to the transaction, such as the target account and amount for a wire transfer. Because developers cannot assume the user's computer is secure, the confirmation should be shown by an external authorisation component.
EU law turns this into a requirement for payment service providers. Commission Delegated Regulation (EU) 2018/389, the regulatory technical standards on strong customer authentication under PSD2, sets out dynamic linking in Article 5:
- Awareness: the payer is made aware of the amount and the payee.
- Specificity: the authentication code is specific to the amount and the payee.
- Invalidation: any change to the amount or the payee invalidates the authentication code.
- Integrity: the confidentiality, authenticity and integrity of the amount and payee are protected through all phases of authentication, including what is displayed to the payer.
- Special cases: for card transactions where funds are blocked, the code is tied to the amount the payer agreed to block; for batches of remote transactions, it is tied to the batch total and the specified payees.
Article 4(3) of the same regulation also limits consecutive failed authentication attempts to no more than five within a given period before blocking, and caps payer inactivity after authentication for online account access at 5 minutes. The PSD2/PSD3 Strong Customer Authentication Guide covers the full SCA regime, exemptions and the PSD3 and PSR proposals; this guide focuses on how to engineer the approval itself.
Exemptions matter for design because they decide when dynamic linking is not triggered. Article 16 exempts remote transactions up to EUR 30 while cumulative amounts since the last SCA stay within EUR 100 or the count stays within five consecutive transactions. Article 18 allows transaction risk analysis exemptions up to exemption threshold values of EUR 100, 250 or 500, subject to the provider's fraud rates staying within the reference rates in the Annex. Any exemption logic must itself be enforced server-side and logged.
Engineering rules from the OWASP cheat sheet
| Rule | What to build | Attack it stops |
|---|---|---|
| Unique credential per transaction (1.5, 2.10) | Challenge includes a nonce, timestamp or sequence number; credential is accepted once, with an atomic check-and-mark-used in state shared by all servers | Replay of a captured code against another transaction |
| Server-side enforcement (2.1) | Default deny; no parameter, missing field or error can skip the check | Parameter tampering, forced errors |
| Method enforced server-side (2.2) | Server decides which method applies; old endpoints for weaker methods are removed | Downgrade to the weakest method |
| Server-generated verification data (2.3) | Transaction details shown for confirmation come from the server's stored record, not from the client | Malware showing faked details |
| Brute-force limits (2.4) | After a set number of failures, restart the whole authorisation; align with the five-attempt cap in RTS Article 4(3) | Guessing short codes |
| Ordered state machine (2.5) | Enter, request, initialise, confirm, respond, execute, each step checked against stored state | Skipping or reordering steps |
| Data locked during authorisation (2.6) | Any modification invalidates the challenge and restarts; modification attempts are logged as attacks | Overwriting the transaction after the challenge is issued (time of check to time of use) |
| Final execution gate (2.8) | Immediately before execution, verify that this exact transaction record has a valid approval | Execution of an unapproved or altered record |
| Short validity (2.9) | Challenge expires within minutes | Relay of codes to an attacker's machine |
| Token and method changes need current approval (1.2, 1.3) | Changing the phone, device or method requires approval with the existing one | Malware re-binding approvals to its own device |
A useful way to implement the binding is a canonical transaction digest. The server serialises the significant fields (for example payer account, payee account, payee name, amount, currency, execution date and a nonce) in a fixed order, stores the record, and uses the digest as the challenge input or signing payload. The confirmation app renders the same fields from the server's record, and the execution gate recomputes the digest from the record about to be executed and compares it with what was approved.
Choosing an authorisation method
| Method | Shows details out of band | Cryptographic binding | Main weaknesses |
|---|---|---|---|
| Static password or PIN re-entry | No | No | Captured once, reusable; does not meet dynamic linking |
| SMS OTP with amount and payee in the message | Yes (on the phone) | Weak: code generated for the transaction, but SMS can be intercepted or redirected through SIM swap | Users skim the text; social engineering; ATT&CK T1111 Multi-Factor Authentication Interception |
| TOTP from an authenticator app | No | No: the code is not linked to any transaction | Does not meet dynamic linking on its own |
| Challenge-response reader (for example CAP) with typed transaction data | Partly: user types key fields | Yes, over typed data | Usability; OWASP notes users must copy data from a trusted source, not the screen |
| Banking app push with device-bound key signing the transaction | Yes, in the app | Yes, signature over server-supplied data | Device enrolment and key protection; mobile malware; approval fatigue |
| Secure Payment Confirmation (SPC) | Yes, in a browser-controlled dialog | Yes: transaction details are included in the WebAuthn assertion | Browser support (Chromium-based browsers only at the time of checking) |
MDN describes SPC as building on Web Authentication: the browser shows the merchant name, payment instrument, amount and currency, and after the user verifies, passes those details to the authenticator, which signs them as part of the assertion. SPC defines a payment WebAuthn extension and the payment method identifier secure-payment-confirmation, and MDN notes it is supported by EMV 3-D Secure 2.3.1 and EMV Secure Remote Commerce 1.3. MDN browser compatibility data lists SPC availability checks in Chrome and Edge, and no support in Firefox or Safari, as of 27 October 2026. The W3C specification is still under active development in the Web Payments Working Group, so check its current status before relying on details. See the FIDO2 and WebAuthn Internals Guide for the underlying assertion format.
Decision guidance
- Regulated EU payment providers: a method that achieves dynamic linking for every non-exempt payment; device-bound app signing is the common choice, with SMS OTP carrying amount and payee as a fallback.
- Card-not-present merchants: rely on the issuer's 3-D Secure challenge, which may use SPC, rather than building your own.
- Non-payment high-risk actions (admin changes, data exports, API key creation): a lighter WYSIWYS confirmation in an authenticated app or a passkey re-assertion with the action described, plus an out-of-band notification.
- Small teams: use a payment provider or identity platform that already implements transaction signing; building device enrolment and key management is a substantial project.
Transaction authorisation in APIs, open banking and agents
In API-based flows the same principle is expressed in protocol fields. OAuth Rich Authorization Requests (RFC 9396) carry structured authorization_details, such as amount and creditor account, so the authorisation server can show the user what they are approving and issue a token scoped to that operation. Client-Initiated Backchannel Authentication (CIBA) supports a binding_message displayed on both the consumption and authentication devices. See the OAuth Rich Authorization Requests (RAR) Guide, the OIDC CIBA Guide and the FAPI 2.0 Security Profile Implementation Guide.
AI agents that make purchases or payments are the newest reason to get this right. An agent acting for a user is a non-human identity holding delegated authority, and a prompt-injected or misaligned agent will happily submit a different payee. Apply the same rules: the user approves a specific mandate (merchant, amount ceiling, expiry) on a channel the agent cannot spoof, the mandate is signed and bound to the agent's credential, and the payment service checks each transaction against it at the execution gate. Never let an agent hold a reusable session that can authorise arbitrary transfers. See the Agent Payments Protocols Guide and the Agentic Commerce Identity Guide.
Implementation and rollout
- Classify operations: list every action that moves money or changes who can (payments, beneficiary add, limit changes, contact detail changes, device enrolment, API key creation). Decide which need per-transaction approval and which fields are significant for each.
- Build the transaction record and state machine: server-side record, canonical digest, explicit states, and one execution gate that every path goes through.
- Integrate the method: app signing, SPC or dynamically linked OTP, with the confirmation text rendered from the server record.
- Test against abuse cases: replayed codes, altered amounts after challenge, skipped steps, parallel requests (race conditions on the used flag), method downgrade parameters and forced errors. See the Race Condition Vulnerabilities Guide.
- Pilot: enable for a staff cohort, then a percentage of customers; watch completion rates and support calls.
- Roll back safely: fall back to a weaker but still dynamically linked method (for example SMS with details), never to session-only approval.
Detection and measurement
Log each transaction's lifecycle with its digest: creation, challenge issued, method used, failures, approval, execution and any modification attempt. Alert on:
- Modification after challenge: OWASP treats any attempt to change transaction data after entry as an attack to be investigated.
- Method change followed by a payment: new device or phone enrolled shortly before a new-payee transfer.
- Repeated authentication prompts: users completing login twice in quick succession, the signature of the "repeat your login" trick.
- Approval from an unusual device or location: relayed codes used from attacker infrastructure.
| Metric | What it shows |
|---|---|
| Share of high-risk operations protected by per-transaction approval | Coverage (target 100% of the classified list) |
| Executions without a matching approved digest | Gate failures (target zero) |
| Fraud losses on approved transactions, by method | Which methods social engineering defeats |
| Approval completion rate and abandonment | Usability cost of the method |
| Modification-after-challenge events per month | Active tampering attempts |
Common failure patterns
- Approval token reusable within the session: one OTP unlocks a "trusted" state for all later transfers.
- Client-supplied confirmation text: the app displays details sent from the browser, so malware shows the user one payee and submits another.
- Legacy method endpoints left live: the new signing flow is bypassed by calling the old SMS endpoint with a parameter.
- Same gesture for login and approval: enables the double-login trick OWASP describes.
- Race on the used flag: two parallel submissions both pass a non-atomic check.
- Social engineering around a correct display: even perfect WYSIWYS fails when a caller persuades the user to approve; pair it with fraud warnings and payee name checks. See the Authorised Push Payment (APP) Fraud Guide.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| Regulation (EU) 2018/389 (PSD2 RTS) | Articles 4, 5, 16, 18 | Authentication code limits, dynamic linking, exemptions |
| OWASP ASVS 5.0 | V7.5.3, V4.1.5, V2.3.3 | Secondary verification for sensitive transactions; per-message signatures; all-or-nothing business transactions |
| NIST SP 800-53 Rev. 5 | IA-2, AC-3, AU-10 Non-repudiation, SC-8, SI-7 | Authentication, enforcement, proof of approval, integrity of transaction data |
| NIST CSF 2.0 | PR.AA-03, PR.AA-05 | Authentication and authorisation enforcement |
| MITRE ATT&CK | T1185 Browser Session Hijacking; T1557 Adversary-in-the-Middle; T1111 Multi-Factor Authentication Interception | Techniques transaction authorisation is designed to defeat |
Practitioner checklist
- Classify every high-risk operation and define its significant fields.
- Generate and store the transaction record server-side and derive the challenge or signing payload from a canonical digest.
- Invalidate the challenge on any change to the record and log the attempt.
- Accept each approval once, atomically, across all servers, within a short expiry.
- Show the details on a channel outside the browser session, rendered from the server record.
- Make login and approval visibly different actions.
- Require approval with the current method to change devices, phone numbers or methods.
- Remove legacy method endpoints and enforce the method server-side.
- Put one execution gate in front of every path that moves money.
- Bind AI agent purchases to user-approved, signed mandates checked at execution.
Standards and references
- EUR-Lex: Commission Delegated Regulation (EU) 2018/389 (RTS on strong customer authentication)
- OWASP: Transaction Authorization Cheat Sheet
- OWASP: Application Security Verification Standard 5.0
- W3C: Secure Payment Confirmation
- MDN: Using Secure Payment Confirmation
- IETF: RFC 9396 OAuth 2.0 Rich Authorization Requests
- OpenID Foundation: Client-Initiated Backchannel Authentication Core
Related NHI Mgmt Group resources: PSD2/PSD3 Strong Customer Authentication Guide · OAuth Step-Up Authentication Challenge Guide · Agent Payments Protocols Guide · Online Banking Security Guide · Payment Gateway Integration Security Guide