How Targeted Ads Deliver Zero-Click Spyware

Citizen Lab's AdFection report shows ad tech repurposed for zero-click spyware — and the identifier leakage we build into URLs is the fuel.

Share

Citizen Lab just published a report called AdFection, and the short version is ugly: the programmatic advertising ecosystem — the same one your attribution links and analytics SDKs plug into — was used as a targeting and delivery pipeline for zero-click mercenary spyware.

Zero-click is the part that should ruin your morning. The target never taps a link, opens an attachment, or installs anything. The infrastructure did all the work.

Why this matters

"Don't click suspicious links" has been the backbone of security training for two decades. An exploit that rides ad infrastructure makes that advice decorative. When delivery ships enabled on effectively every phone by default, user behavior is irrelevant — only engineering controls matter.

The second reason hits closer to home. This pipeline runs on identifier leakage, and we're the ones leaking. Device IDs, IPs, and stable IDs in query strings are the targeting fuel.

How it works

When a page or app loads an ad slot, a real-time bidding request goes out. It carries the advertising ID, IP address, user agent, often coarse location — broadcast to a crowd of ad firms in milliseconds. The bidstream is functionally a real-time "where is this device right now" lookup that anyone with an ad budget can query.

Targeting a specific device or IP segment is a normal, documented product feature. Great for a shoe brand. Perfect for finding one person.

Then there are redirect chains. Every ad click hops through several servers, each logging the full URL and appending its own identifiers. Whoever operates a hop sees everything.

Zero-click closes the loop: the act of rendering the "ad" is the attack surface. No prompt, no notification, nothing to train users against.

Where this helps

  • Outbound email links. Confirmation links with ?user_id=42 put a stable identity into every log along the way. Use opaque, rotating tokens mapped server-side.
  • Share links and OAuth callbacks. Audit what identifiers your redirect chains append — intermediaries log URLs wholesale.
  • Mobile SDK audits. Every ad and analytics SDK in your app feeds the bidstream with device identifiers. Make each one justify its presence.
  • Webhooks and logs. Treat query strings as public. They land in access logs at every hop.

Watch out

This is mercenary-grade targeting — journalists, activists, executives. Don't torch your routing layer over it. Do fix identifier hygiene; your privacy compliance effort wants that anyway.

Ad blocking helps but doesn't close the hole. IP-based targeting survives blockers, and fingerprinting works from fonts, screen metrics, and timing. And attribution links are load-bearing product features — strip identifiers surgically, or your growth team will come find you.

Try it yourself

Run this on your top five outbound URLs. It overmatches on purpose — you want to eyeball everything identifier-shaped:

# audit_link.py — flag identifier-shaped params in any URL
from urllib.parse import urlparse, parse_qsl

LEAKY = ("id", "user", "gclid", "fbclid", "idfa", "device",
         "ip", "email", "phone", "token", "session")

def audit(url: str) -> list[str]:
    return [k for k, _ in parse_qsl(urlparse(url).query)
            if any(t in k.lower() for t in LEAKY)]

print(audit("https://app.example.com/share?user_id=42&fbclid=IwAR2&token=abc"))
# ['user_id', 'fbclid', 'token']

TL;DR

  • What changed: Citizen Lab's AdFection report shows ad-tech targeting repurposed into a pipeline for zero-click mercenary spyware.
  • Why it matters: the targeting fuel is identifier leakage — and "don't click links" defends nobody against zero-click.
  • Try today: audit your outbound URLs for identifier params and swap stable IDs for opaque, rotating tokens.