- No third-party scripts on pages that can move money
- Remaining vendor scripts self-hosted, pinned and integrity-checked
- Browser talks only to the e-wallet's own backend-for-frontend
- Transfers and withdrawals need fresh confirmation, not just a live session
- Unexpected script or header changes on sensitive pages raise alerts
Anonymised composite. Client names, identifying details and confidential figures are withheld; public facts are cited in the references.
The situation
An e-wallet in Indonesia served users through a mobile app and a web app. The web app let users top up, pay merchants, transfer to bank accounts and withdraw. Over the years, marketing, product and support had added scripts from analytics providers, a tag manager, a chat widget, a session recorder, a performance monitor and several advertising pixels. Most loaded on every page, including the transfer and withdrawal flows, and several were loaded directly from vendors' servers.
Why now. On 29 October 2026, malicious code replaced a third-party performance script loaded by Polymarket's website and used signed-in traders' sessions to withdraw funds; Polymarket put the loss at about $2.7 million12. No passwords or keys were needed: the script simply acted with the access the open page already had1. The card side of the business was already subject to PCI DSS v4 requirements that scripts on payment pages be authorised and protected from tampering, and that changes to payment pages be detected3, and Indonesia's Personal Data Protection Law applies to the personal data those scripts could see4. The board wanted the risk removed, not just documented.
What had to be true
- No third-party code on money-moving pages.
- Every remaining script known, justified and integrity-checked, served from the e-wallet's own domain.
- The browser holds as little power as possible: no long-lived tokens, no direct calls to vendors.
- A live session is not enough to move money: transfers and withdrawals need fresh confirmation.
- Changes are noticed: unexpected scripts or header changes on sensitive pages raise alerts.
Architecture
The data flow, end to end
- LoadThe transfer page loads only first-party scripts under a strict policy
- RequestThe browser calls the e-wallet's backend-for-frontend, never a vendor directly
- ConfirmThe user confirms the transfer with a PIN or biometric, bound to the amount and recipient
- CheckLimits and velocity rules run server-side before execution
- ExecuteThe transfer runs; analytics events are sent server-side, not from the page
- WatchMonitoring compares the delivered page and headers with the approved version
The hard part: taking scripts away from the teams that rely on them
Every script had an owner who needed it: marketing measured campaigns, support used the chat widget, product watched session recordings. Simply deleting them would have failed politically and practically. The team ran an inventory first, recording for each script what it did, who owned it, which pages it loaded on and what data it could read. Many turned out to duplicate each other or to have no current owner.
The bigger change was architectural. The web app moved to a backend-for-frontend: the browser talks only to the e-wallet's own server layer, which holds session tokens and calls internal services and vendors on the user's behalf. The OpenTelemetry demo's front-end shows the same shape: client-side code calls the app's own API routes, which then call the backend services5. With that in place, analytics and marketing events could be sent server-side, so most tags no longer needed to run in the browser at all.

For the scripts that remained, such as the chat widget on help pages, the team self-hosted pinned versions with integrity hashes, so a change at the vendor could not silently change the code running in users' browsers, and listed every allowed source in a Content Security Policy with violation reporting turned on. Vendor updates became a deliberate change, reviewed like any other dependency.
Treat every third-party script as a contractor with your user's keys. Keep contractors off the floor where money moves, and check the ones you keep every time they change.
How it ran
- Script inventory
- CSP and integrity rules
- Page monitoring
- Backend-for-frontend
- Step-up confirmation
- Server-side events
- Justify each script
- Move to server-side data
- Approve vendor changes
- Strip scripts from transfer pages
- Step-up on withdrawals
- Lower limits for new devices
- Script register
- CSP in report mode
- Self-host kept scripts
- Backend-for-frontend
- Server-side analytics
- CSP enforced
- Page change monitoring
- Violation alerts
- Vendor change reviews
Key decisions and trade-offs
| Decision | Alternative | Why |
|---|---|---|
| No third-party scripts on money pages | Monitor them closely | Removal beats detection where money moves |
| Backend-for-frontend | Browser calls services and vendors directly | Tokens and integrations stay server-side |
| Server-side analytics | Browser tags | Same insight, far less code in the page |
| Self-hosted, integrity-checked scripts | Load from vendor servers | Vendor compromise cannot change running code |
| Fresh confirmation per transfer | Trust the active session | A hijacked session alone cannot move money |
What I'd do again, and differently
Again: strip the money pages in week one. It removed most of the risk before the longer re-architecture began. Differently: run the Content Security Policy in report-only mode from the first day of the inventory; its reports found scripts that nobody had listed. Related: architecture lessons from the Binance hack, the 2 November tech news, securing AI coding tools and where I work.
If you run a wallet, marketplace or fintech in Indonesia or across Southeast Asia, see the Singapore and Southeast Asia page, or analyse your challenge and bring the result to a call.
- 1Hackers Steal About $2.7 Million From Polymarket Traders via Hijacked DebugBear ScriptThe Hacker News · Nov 2026
- 2$2 Million+ Drained From Polymarket Traders in New Supply Chain AttackSecurityWeek · Oct 2026
- 3
- 4Data Protection & Privacy 2026: Indonesia, Trends and DevelopmentsChambers and Partners · 2026
- 5Front-end Overhaul of the OpenTelemetry Demo (Go to Next.js)OpenTelemetry blog · 16 Nov 2022