Inspiration

Denmark has a scam problem that is getting worse, not better.

  • 333M DKK lost to phone scams in 2024 (Finans Danmark).
  • +400% growth in QR-code phishing ("quishing") since 2023.
  • 194 tracking methods per visit on a typical Big Tech site.
  • 274,000 Danes hit by phone-based fraud last year.

The people most at risk — our parents and grandparents — are the last group a single SaaS product is ever built for. So instead of one app, we built four — each solving one attack vector, all sharing the same backend, the same design system, and the same mission: put the defender back in control.

(Working codename in the demo video: Skjold — Danish for "shield".)

What it does

Phishing Shield is four products under one roof.

1. Data Shield — Stop what Big Tech takes.

A browser extension and web dashboard that classifies 194 known tracking and data-collection methods per site and blocks 71 of them. A three-column ledger shows, per site: what the platform collects, what we allow, and what we intercept. Users can generate a "Second You" persona to spoof the data Big Tech expects. Stack: Rust/Axum backend · Next.js 16 dashboard · Chrome MV3 extension (CSP-safe content injection) · Postgres on Railway.

2. QR Guard — Don't scan blind.

An Expo / React-Native mobile app that sits between the camera and the URL. Every decoded link goes through three reputation layers: local heuristics (punycode, shorteners, redirect depth), Google Safe Browsing v4, and policy allowlists. Verdict: allow, warn, block — with a human-readable reason. Fail-open design keeps L1 heuristics running even if the external API is down. Stack: Rust/Axum on Railway · Expo SDK · EAS preview build.

3. Prince Trainer — Skam-fri phishing træning.

A phishing simulator aimed at Danish families. Realistic Sundhed.dk, MitID, and KY scam SMS are sent to enrolled parents; clicking the link opens a STOP debrief explaining the three tells (domain, urgency, unsolicited renewal). No shaming, no fake "you failed" screen. Stack: Sinch SMS + scheduled cron + client-only sample-phish preview for judges.

4. Familieværn + AI Grandma — En dansk AI tager telefonen.

A call screener that answers unknown Danish numbers, transcribes in real time, and classifies fraud in under a second. When it smells like a scam, the call is seamlessly routed to AI Grandma — a plausible elderly Danish voice (ElevenLabs) that wastes the scammer's time while the family phone stays silent. The operator UI shows every active call, live transcription, and per-session logs. Stack: Sinch Voice · ElevenLabs TTS · Next.js operator console · Rust backend.

How we built it

  • One team, one repo, four product arms with clear ownership — Fredrik (Data Shield), Patrick (QR Guard + Prince Trainer), Hans (Familieværn).
  • Shared infra: one Railway project with shared Postgres (tables prefixed shield_*, corpus_*, …), one Vercel team, one GitHub repo. No microservice sprawl.
  • Shared design system: Fraunces + Inter + IBM Plex Mono on a paper background with a copper accent — inspired by Danish editorial design, deliberately not "another AI dashboard."
  • Shared Rust backbone: Axum + SQLx + fail-open external-API pattern. Every arm reuses the same error types, request-id layer, and reputation-scoring shape.
  • Cross-arm corpus: patterns surfaced by any arm (e.g. a phishing SMS template from Prince Trainer) seed the reputation layer used by QR Guard, and vice-versa.
  • The 55-second submission video was generated with Remotion (React → MP4) — because why hand-edit footage when you've already got a design system?

Challenges we ran into

  • Chrome MV3 CSP headaches: every config-injection path the web suggests is broken in some way. We landed on a dataset + CustomEvent handshake that doesn't violate CSP and is stable across Instagram, X, and Temu.
  • Sinch Voice + ElevenLabs latency in the Familieværn flow: getting AI Grandma to sound like she's actually on the line, not pre-recorded, required streaming TTS over a fixed-length silence buffer so pacing matches human speech.
  • Danish-first content is hard: the scam corpus (Sundhed.dk, MitID, KY, SKAT) doesn't exist as a clean dataset anywhere. We hand-curated ~20 templates and designed the schema so the community can extend them.
  • Deadline triage: we originally planned a unified hub app; we consciously cut that scope on Sunday morning and kept the four products on their own URLs rather than ship a half-baked shell.

Accomplishments we're proud of

  • All four arms deployed and reachable by judges — not a slide deck.
  • Rust backend on Railway passes live phishing-URL traffic through Google Safe Browsing end-to-end.
  • Data Shield extension successfully intercepts tracking on Instagram, X, and Temu today.
  • AI Grandma actually wastes scammers' time — in our tests, an average scam call went from 42s (human hang-up) to 2m47s (Grandma keeps them talking about the coffee).
  • Zero-auth demo paths on every product so the judges never have to sign up to feel it work.

What we learned

  • A "platform" is cheaper to build than four separate products if you pre-commit to one backend, one design system, and one deploy target on day one.
  • For Danish consumers, language matters more than UX polish. An app in English targeted at Danes is a trust red flag.
  • Fail-open beats fail-closed when the user is non-technical. The moment a QR scanner blocks a legitimate URL, the user uninstalls. Every external API here degrades to "local heuristic + honest copy" instead of a hard error.
  • Remotion + a design system = submission videos in hours, not days.

What's next for Phishing Shield

  • iOS builds for QR Guard (we only shipped Android APK for the demo).
  • Danish telco redirect shared between Familieværn and AI Grandma once we agree with TDC / Telenor.
  • Community corpus: let any user submit a scam SMS/URL they received; route it through a moderation queue; push it to every arm's reputation layer within 10 minutes.
  • MitID + Sundhed.dk partnerships — both are the phishers' favourite disguises, and both have an obvious incentive to endorse a defender.

Built With

Share this project:

Updates