9 open38 to send

HOW IT WORKS · the product in one minute

Someone fakes ShopNova's site. BrandWatch finds it, proves it, takes it down.

Six steps, shown on this workspace's real data: ShopNova, its look-alikes, a cloaked kit and the attacker behind it. Press play, or scroll.

or scroll ↓ skip to the details
Built by Itay Azulay · a solo project Python · FastAPI · SQLAlchemy · Playwright · CI on SQLite & PostgreSQL
STEP 1 / 6 · LEARN

First, it learns what the real ShopNova looks like.

BrandWatch opens shopnova.com once and keeps a fingerprint: the favicon's hash, a picture of the homepage, its colours, its login form and the words a phisher would copy.

  • AI reads the site and writes the Google searches an attacker would target.

Every suspect is later compared against this fingerprint, not against a guess.

https://shopnova.com/
the real ShopNova homepage
Favicon fingerprint
mmh3 -2029202433
Colours
Login form
email + password field
Words a phisher copies
shopnovashopsmarterelectronicshomemore
AI · searches attackers target
“shopnova login”“shopnova sign up”“shopnova support”
✓ Fingerprint v3 saved — the reference for every comparison
STEP 2 / 6 · FIND

Then it hunts for look-alikes — before anyone reports them.

Typo domains on 1,000+ endings, new HTTPS certificates as they are issued, yesterday's registrations and Google results — nothing has to be on a blocklist first.

  • Social: Facebook pages, Instagram profiles and ads under the brand's name, read by an AI.
  • AI assistants: ChatGPT and Gemini are asked what a customer asks; a phone or e-mail that is not on the brand's site becomes a finding.

Found before anyone reports it — the brand's own sites and big platforms are dropped first.

Certificate logs 58 Analyst URL scan 38 Look-alike names 29 Facebook / Instagram ads 11 AI answer (ChatGPT / Gemini / Google AI Mode) 5 Facebook pages / Instagram profiles 5 Google search 3
0look-alike domains found for ShopNova
  • shopnova-login.comAI answer (ChatGPT / Gemini / Google AI Mode) critical
  • shopnova-refund.netFacebook pages / Instagram profiles critical
  • shoqnova.comGoogle search critical
  • shopnowa.comGoogle search critical
  • shopn0va.comGoogle search critical
  • shospnova.comLook-alike names watching
  • sholpnova.comLook-alike names watching
  • shapnova.comLook-alike names watching
STEP 3 / 6 · VISIT

It visits every site the way a victim would.

Many phishing kits hide from security scanners: a harmless page for datacenter IPs, the fake login only for real people. So BrandWatch also visits as a real person.

  • A real Chrome: its User-Agent, Accept-Language, client hints, language and time zone all agree — no "HeadlessChrome" giveaway.
  • A real address: through a residential or a mobile 4G / 5G proxy (or both) in the brand's country, as a desktop and / or a phone.
  • A locked-down browser that can't reach internal systems; everything it sees is kept as evidence nobody can edit.

The score uses what a victim sees, not what the kit chose to show a scanner.

suspectshopnova-giftcard.com
🤖Security scanner
datacenter IP · bot user-agent
what a scanner sees
saw: a harmless page
👤Real visitor
home IP · real Chrome headers
what a victim sees
saw: a fake ShopNova login
⚑ Cloaking caught: the page changes for scanners. That alone is evidence of bad intent.
the real ShopNova
compared with the real ShopNova
100% the same picture
STEP 4 / 6 · SCORE

It scores the site — and shows its work.

50 signals in 7 capped groups, each worth fixed points: does the address use the brand, does the page look the same, does it ask for a password, how new is it, is it hiding.

  • The same evidence always gives the same score; AI is a second opinion and never changes the number.

No black box: every point traces back to a piece of evidence.

0RISK / 100
hides from datacenter IPsEvasion+25
identical faviconVisual+22
looks like the real siteVisual+18
asks for a passwordBehaviour+14
brand name in the domainIdentity+12
cloned login formVisual+12
registered < 7 days agoFreshness+10
+ 6 more signal(s), capped per group
medium 25high 50critical 75
severity CRITICALconfidence 100%5 independent groups agree

Registered 4 days ago. Puts the ShopNova name in its address, copies ShopNova's favicon, homepage and login form and asks for a password. It hides from security scanners: the real page only appears to a normal visitor (home IP / browser).

STEP 5 / 6 · DECIDE & MAP

A person decides. Then it maps the attacker.

Nothing is confirmed automatically: an analyst reads the evidence and presses Confirm. From that one site, BrandWatch follows what the attacker reused — server, certificate, favicon, tracking code, owner — to the rest of the operation.

  • Neighbours that only share a cheap server are dropped as noise, with the reason written down.

One fake site leads to the whole operation, and every indicator exports to a SIEM as STIX 2.1.

criticalxn--shopnov-8fg.com Confirm phishing✓ Confirmed by an analyst➤
shared server (passive DNS) xn--shopnov-8fg.com xn--shopnov-8fg.com 203.0.113.134 203.0.113.134 SERVER
2 pieces of the attacker's setup1 phishing sites linked0 dropped as noise
STEP 6 / 6 · TAKE DOWN

Finally, it drafts the takedown.

A request backed by the evidence, addressed to the people who can pull the site: the registrar, the hosting provider and the CDN — contacts found automatically.

  • 26 report portals (browsers, anti-virus, blocklists) so the site is blocked for everyone while the takedown is pending.
  • A fake Facebook / Instagram ad or page gets Meta's report flow and a ready-to-paste report.

BrandWatch never sends anything by itself: a person reviews and sends, and every step lands in the audit log.

Toabuse@mock-registrar.example
SubjectPhishing site impersonating ShopNova — takedown request BW-570AE512: shopn0va.com
RefBW-570AE512
Hello Mock Registrar LLC abuse team, We are reporting a website that impersonates ShopNova and appears designed to harvest user credentials. Impersonating URL : https://shopn0va.com/ Hostname : shopn0va.com First observed : 2026-10-12T06:41:46.604012
RegistrarMock Registrar LLC
abuse@mock-registrar.example
HostingBulletproofHost BV
abuse@bulletproofhost.example
CDNCDN / DNS provider
none found for this site
Google Safe BrowsingMicrosoft SmartScreenKaspersky OpenTIPESETBitdefenderTrend Micro Site SafetyAvast / AVGSophosAviraDr.WebFortiGuard (Fortinet)Symantec / Broadcom Site ReviewTrellix / McAfee TrustedSourceZscaler Site ReviewPalo Alto Networks Test A SiteOpenText BrightCloud (Webroot)Cisco TalosNetcraftAPWG (Anti-Phishing Working Group)SpamhausPhishTankURLhaus (abuse.ch)FBI IC3 (US)NCSC Report a suspicious website (UK)Scamwatch (Australia)Canadian Anti-Fraud Centre
👤A person reviews and sends it. Draft → approved → sent → taken down, every step in the append-only audit log.
Find→Prove→Decide→Map→Take down

That's BrandWatch, in the six steps above. Every step is explainable, every piece of evidence is tamper-proof, and a person decides everything that matters.

About this project · numbers read from the code, not typed by hand

0
signals in 7 groups
0
combination rules · 5 FP penalties
0
providers in 15 fallback chains
0
recorded golden scenarios
0
DB-enforced immutable tables
0
automated tests in 73 files
0
REST API operations (OpenAPI)
0
Alembic migrations · SQLite & PostgreSQL

Stack: FastAPI · SQLAlchemy 2 · Alembic · Jinja2 · Playwright (Chromium) · httpx · dnspython · cryptography. Scoring version v7-f1ba3ebf. CI: lint · test-sqlite · test-postgres.

Go deeper

For the questions after the demo: every step with its exact APIs and limits, the presenter's script, the engineering, and the glossary every “?” on the site links to.

The pipeline, step by step· 13 stages in order — “see it” opens a real example, “More info” shows the exact APIs, limits and code
1 · favicon, screenshot, login form, keywords
Learn the real site

Fingerprint the brand's real site: favicon hash, screenshot hash, colours, the login and sign-up pages, keywords — and an AI-written list of the Google searches a phisher would target.

see it →
2 · typos, new certificates, new domains, Google, Facebook / Instagram ads
Find look-alikes

Five streams look for look-alikes: typo and homoglyph permutations on 1,000+ TLDs (DNS-checked), new TLS certificates, yesterday's newly registered domains, Google results, and the urlscan archive — plus fake Facebook / Instagram accounts and ads, and what ChatGPT, Gemini and Google AI Mode tell users about the brand's contacts.

see it →
3 · merge, drop official & known platforms
Clean the list

One candidate per URL with every stream that found it; official domains, whitelisted partners and big platforms (YouTube, app stores) are dropped before anything is fetched.

see it →
4 · DNS, WHOIS, screenshot, HTML
Visit in a sandbox

Each site is visited in a sandboxed browser behind an SSRF guard: DNS, WHOIS / RDAP, TLS, screenshot, HTML, favicon and reputation feeds — all stored as evidence.

see it →
5 · fetch as a bot, a victim and a home IP
Catch cloaking

Kits that hide from scanners are fetched again as a bot, as a victim link, from a Google referer — and as a person: a real Chrome (User-Agent, Accept-Language, client hints, language and time zone) through a residential or a mobile 4G / 5G proxy, or both, as a desktop and / or a phone. The score uses what a victim sees.

see it →
6 · 50 signals in 7 groups
Compare with the brand

50 signals in 7 groups compare the site with the brand: identity tricks, visual copy, what the page asks for, shared infrastructure, reputation, freshness, evasion.

see it →
7 · risk 0–100 + confidence
Score & explain

Deterministic and versioned: points per signal, a cap per group, combination rules for known kit shapes, false-positive penalties — plus a separate confidence axis. AI and a classifier give advisory opinions only.

see it →
8 · Medium and above go to an analyst
Raise a finding

Medium and above become a finding for an analyst; the rest stays on the watchlist and is re-checked on a schedule (a parked domain that grows a login form jumps to the front).

see it →
9 · what this scan did, step by step
Report

The live console narrates every step while it happens and ends with a plain-language report; an engineering trace records every provider call, AI prompt and the scoring maths.

see it →
10 · verdict
Confirm or dismiss

The finding page explains itself in two sentences and shows every signal, its points and the evidence. A human decides; the reason goes to the audit log and the training set.

see it →
11 · investigate
Site & network investigation

VirusTotal-style lookup on the finding page itself: detections, DNS, certificate, RDAP and abuse contact, WHOIS history (every past owner, and details hidden later), passive DNS, every other site on the server, urlscan similar pages.

see it →
12 · map the attacker
Attack infrastructure

From one confirmed site, a budgeted pivot over shared servers, certificates, favicons and tracking IDs; co-hosted noise is triaged out. Indicators export as STIX 2.1.

see it →
13 · take it down
Takedown

An evidence-backed request with an audited lifecycle; contacts for the registrar, the hosting provider and the CDN; 26 blocklists, anti-virus and abuse-report portals. BrandWatch never sends anything itself.

see it →
Guided tour · 8 stops· a ten-minute walk through the app, with the questions people ask
  1. Dashboard — the mission line and the five-step strip

    “BrandWatch finds sites impersonating a brand — on the web and in Facebook / Instagram ads — proves it with tamper-proof evidence, maps the attacker's servers and drafts the takedown. A human decides every step.”

    Likely question: what's real here? → In demo mode every external service is a recorded scenario; the same code calls VirusTotal, crt.sh, Google and Chromium in live mode.

  2. The brand page — tick “include fingerprinting”, press START SCAN

    “First it learns what the real site looks like, then it hunts for copies on five streams.”

    Likely question: how do you find domains that don't exist in any list yet? → Permutations checked in DNS, new certificates in CT logs, yesterday's registrations.

    Likely question: what about ChatGPT and Gemini? → With AI answers on, the approved questions (support phone, contact, login, fraud) are asked to ChatGPT, Gemini and Google AI Mode; every contact in the answers is compared with the ones on the brand's own website, a mismatch gets a "show me the official page" follow-up, and BrandWatch opens the cited pages itself before it raises a finding.

    Likely question: what about social media? → Facebook pages by name (Meta's page search, every country) and Instagram / Facebook profiles Google knows; each one's page history, logo, links and posts are checked and an AI reads the content. Fakes become findings with a Report-to-Meta box, a link in their bio goes to the website checks, and the brand's own accounts are never flagged. Ads about the brand are searched too, per country.

  3. The live scan console — then “▶ replay highlights”

    “Every step is narrated as it happens; the report at the bottom says what the scan did in plain words.”

    Likely question: what if VirusTotal is down? → Retries with backoff, a circuit breaker, then the next provider in the chain; the alert panel says what happened and how to fix it.

  4. A cloaked kit — read the two-sentence summary, then the three screenshots

    “This kit shows a blank page to scanners and the login page to real visitors. We fetch it like a victim would.”

    Likely question: why is VirusTotal at 0? → It's days old; blocklists lag. Unknown is never treated as clean.

  5. Explain Finding — signals, group caps, the score line, “open the arithmetic”

    “Deterministic, explainable scoring: every point traces back to evidence. Risk and confidence are separate axes. The AI is advisory.”

    Likely question: false positives? → Penalties (old domain, redirects to the brand), a whitelist, and a golden-dataset regression gate (precision / recall ≥ 0.90).

  6. Press Confirm phishing, then Investigate site & network

    “Confirming maps the attacker's infrastructure automatically. The investigation tabs on the finding page replace twenty minutes of VirusTotal, urlscan and RDAP tabs.”

  7. The attack infrastructure map — drag the graph, read two triage reasons

    “One site led to the whole operation. Noise is triaged out with a reason; the indicators go to a SIEM as STIX.”

  8. “Three channels — registrar, host, CDN — plus the blocklists. Every step is in an append-only audit log the database won't let anyone edit.”

Under the hood· the engineering an interviewer asks about

SSRF guard & sandbox

Every fetch: validate the URL → resolve A/AAAA → fail closed on 24 blocked networks (private, loopback, cloud metadata) → connect pinned to the validated IP with Host + SNI → re-validate every redirect hop (≤ 5) → size ≤ 5.0 MB, timeout 15.0 s.

The same policy gates every Chromium sub-request. Limits are frozen in code — no brand, workspace or env var can change them.

security/fetcher_guard.py · security/limits.py · see it in Settings

Immutable evidence

10 append-only tables: database triggers reject UPDATE and DELETE — even for an admin, on SQLite and PostgreSQL. Artifacts are content-addressed: the SHA-256 is the file name.

Each finding links its evidence with a role (primary, supporting, contradicting, context): a chain of custody for a takedown or a court.

db/models · migrations/001 · evidence/store.py · see it on a finding

Provider resilience

Every external call goes through one wrapper: TTL cache → budget check → circuit breaker → token bucket → retry with backoff (honouring Retry-After) → the next provider in the fallback chain.

A bad key disables the provider for the job instead of failing 500 calls; "unknown" is never treated as clean.

providers/base.py · providers/registry.py · see the alerts panel

Cost ledger & budgets

Every paid call is recorded with its cost; daily call and spend caps are checked over the trailing 24 h before the call, so a scan stops spending instead of overspending.

providers/ledger.py · budget meter

Golden dataset gate

65 recorded scenarios (16 phishing incl. cloaked kits, 17 legitimate, 15 brand-related legitimate, 10 suspicious-but-not-phishing) run through the real pipeline in CI.

The build fails below precision 0.9 / recall 0.9 / FP rate 0.05; last measured 1.00 / 1.00 / 0.00. The same corpus drives the $0 demo.

demo/golden/*.jsonl · tests/test_golden.py · quality card

Durable live events

Each scan writes an ordered event stream (sequence-numbered, secrets redacted) before publishing it over SSE; a refresh resumes from the last event. Cancellation is cooperative at safe checkpoints.

events/emitter.py · api/scans.py · trace.py

Secrets, tenants & roles

API keys are envelope-encrypted (random 32-byte key per record, AES-256-GCM, bound to workspace:provider). Passwords: Argon2id. Personal API tokens are stored as SHA-256 only; a read-scoped token caps even an admin at viewer.

Every query is workspace-scoped; RBAC (admin / analyst / viewer) is identical in the UI and the API.

keys.py · config/secrets.py · tenancy.py · api/auth.py

Tests & CI

659 test functions in 73 files: schema and trigger enforcement, SSRF cases, provider resilience, every UI page, the golden gate. CI runs lint, test-sqlite, test-postgres, including migrations up and down on PostgreSQL 16.

tests/ · .github/workflows/ci.yml

Trust & safety

  • A human decides every verdict and every takedown; nothing is ever sent automatically.
  • Residential IPs are used to look like a victim, never to interact; probes never submit forms.
  • The AI only gives advisory opinions under a strict JSON schema, with the page text framed as untrusted.
  • Only brands you are authorised to protect; every action is in the append-only audit log.
Glossary· every “?” on the site links here
Baseline
The fingerprint of the brand's real site — favicon hash, screenshot hash, colours, login pages, keywords. Every suspect is compared against it.
Candidate / watched domain
Any domain discovered for a brand. It lives on the Watchlist until it scores high enough to become a finding, expires, or is dismissed.
Finding
A candidate that scored Medium or higher. An analyst confirms it as phishing or dismisses it; nothing happens automatically.
Signal
One piece of evidence (e.g. 'identical favicon'). 50 signals in 7 groups; each adds points.
Group cap
Each group can add at most its cap, so ten weak visual hints never outweigh one strong behaviour signal.
Risk score
How dangerous the site is, 0–100. Medium ≥ 25, High ≥ 50, Critical ≥ 75. Combination rules can raise the severity.
Confidence
How complete and consistent the evidence is (breadth, completeness, provider agreement) — separate from risk.
Cloaking
A kit that shows a harmless decoy to scanners and the phishing page to victims. BrandWatch fetches as a bot, as a victim link, from a search referer and from a home IP.
Detection track
Light, Standard or Deep: which discovery streams run, how many sites are visited, how often the watchlist is re-checked.
Attack infrastructure
The map built from one confirmed site: every server, certificate and sister domain it shares, triaged so reverse-IP noise is excluded. The pivot is budgeted (at most 2 hops, 100 nodes, a fixed number of API calls) and those limits are frozen in code.
Advisory opinions
An AI model and a trained classifier each give a second opinion on Medium+ findings. The page text is passed as untrusted input and the answer must match a strict JSON schema. Shown for context only: the deterministic score never depends on them.
IOC
Indicator of compromise: a domain, IP, certificate hash or tracking ID a firewall / SIEM can block. Exported as CSV, JSON or STIX 2.1.
Takedown
The request to remove a site. Draft → review → approved → sent → taken down; sent to the registrar, the hosting provider and the CDN, and reported to blocklists.
Evidence
Every screenshot, HTML page, DNS / WHOIS answer and reputation lookup, stored append-only with its SHA-256 — the database rejects edits and deletes.
Discovery stream
One way of finding look-alikes: look-alike names (dnstwist), new certificates (CT), newly registered domains (NRD), Google search, the urlscan.io archive, social media, ads. A track decides which streams run.
dnstwist
Generates the names a phisher would register — typos, swapped letters, other TLDs, look-alike Unicode — and checks in DNS which of them exist.
Certificate transparency (CT)
Every HTTPS certificate is published in public logs within minutes; a new certificate carrying the brand's name is often the first sign of a kit.
Newly registered domains (NRD)
Yesterday's list of every newly registered domain (about 70,000 a day), searched for the brand's name.
urlscan.io
A public archive of scanned web pages: past scans that mention the brand, and a screenshot of a site that blocks BrandWatch.
Home / mobile IP probe
A visit through a home (residential) or 4G/5G address, for kits that show the real page only to people, never to a datacentre. Needs a proxy and a GB budget.
STIX 2.1
The standard file format security tools exchange threat indicators in; the infrastructure map's indicators can be exported as STIX for a SIEM or a firewall.
Golden dataset
Recorded, hand-labelled scenarios (phishing, cloaked kits, scam shops, legitimate sites) the real pipeline is run on in every build; precision and recall are measured on them.
TLD set
Which top-level domains dnstwist tries: common (.com .net …), popular (about 100) or all (about 1,280).
Vertical
The kind of business ("footwear and apparel", "crypto exchange") — read by the AI from the official site, used to pick the right Google queries.
Who sells it
Only the brand (a service, an app, a bank) or other shops too: then scam shops advertising its products are hunted as well.
Demo mode
Recorded scenarios replace every external service: the full pipeline runs deterministically, offline, at $0.