// CASE STUDY — Security
ScamChecker
Solo design, build, and ongoing operation
Scam analysis used by 1,000+ people, with an anonymous web scanner and iOS and Android apps. Explains the warning signs behind each risk verdict.
Source code is private.

Problem
People need to understand why a message or link looks suspicious before deciding what to do next.
My Contribution
I designed, built, and operate the web scanner, detection engine, community reporting system, and companion apps.
Key Decisions
Run scoring on-device, explain individual signals, and send extracted indicators to reputation services instead of raw pasted messages.
Results
Used by 1,000+ people, with a live web scanner and apps available on the App Store and Google Play.
Behind the Build
ScamChecker started from a pattern I kept seeing at work: the rise in phishing and scam SMS targeting Australians, and how few tools explain why a message is suspicious rather than just giving a verdict. I designed, built, and operate the entire product — the detection engine, the web app at scamchecker.app, and companion apps — and it has grown past 1,000 users.
The design principle behind everything is that a safety tool should never create its own risk. The free scanner is anonymous by default, requires no sign-up, and runs scoring on-device. Optional account features are separate from the scanner. When the server is consulted at all — for reputation enrichment against the community-reports database, AbuseIPDB, and Google Safe Browsing — it receives only extracted indicators like URLs and phone numbers, never the raw text a user pasted. Community scam reports are scrubbed of card numbers and one-time codes before anything is stored, and abuse prevention (rate limiting, duplicate-vote protection) works from hashed network identifiers instead of user identities, so protecting the service never meant identifying the people using it.
The engine itself is a weighted multi-signal scorer: a curated library of urgency, impersonation, and financial-pressure patterns, brand-lookalike URL detection built on tldts and Levenshtein distance, premium-rate phone heuristics, and document/QR scanning with client-side OCR. Every signal contributes to a transparent per-signal breakdown, because the goal is educational as much as protective — users learn what to look for, not just whether to trust one message.
Built With
Highlights
- 1,000+ users, with a free scanner that does not require an account or login to run a check.
- On-device scoring engine: weighted regex signal library, brand-lookalike URL detection (tldts + Levenshtein), phone-number risk heuristics, and document/QR scanning with client-side OCR.
- Server enrichment without content exposure — reputation checks against the community-reports database, AbuseIPDB, and Google Safe Browsing receive extracted indicators only, never the pasted message.
- Community reporting loop: user reports are matched into opaque report groups so one person's report protects everyone else, with helpful-vote ranking and redaction of card numbers and one-time codes before storage.
- Mobile companion apps available on the App Store and Google Play, alongside the web scanner. The iOS app shares the scoring engine through Expo and React Native.
- Grew into a destination site: scam-awareness guides, FAQ schema, a directory of international scam-reporting bodies, and SEO content targeting high-intent search queries.
Security Considerations
- The free scanner does not require an account. Optional passwordless sign-in uses magic links and PKCE without gating a check; the app and its supporting services still require security maintenance.
- User safety over data collection: history stores verdict metadata only, never pasted content; message reports are redacted (cards, OTP codes) before they touch the database.
- Outbound URL intelligence hardened against SSRF and DNS rebinding: global-unicast-only policy, address-pinned connections, bounded redirects, and final-destination rescoring.
- Fail-closed engineering throughout — unavailable reputation sources report as unavailable rather than falsely clean, and signed (Ed25519) threat-intel updates are rejected rather than trusted when verification can't complete.
- Abuse prevention without identity: atomic fixed-window rate limiting keyed on hashed, window-scoped network identifiers instead of user accounts.
Development Timeline
Problem Identification
Mar 2024Tracked the rise in phishing and scam SMS targeting Australians. Mapped common scam patterns, red flags, and the gaps in existing detection tools.
Scoring Engine
May 2024Compiled the indicator library and designed the weighted scoring system: a confidence score with a per-signal breakdown so users learn what to look for, not just whether to trust a message.
Multi-Input Support
Aug 2024Extended the checker to emails, URLs, and phone numbers, then added OCR-based image scanning and file uploads (PDF, DOCX, TXT) with size limits — all processed client-side.
Custom Domain & Branding
Dec 2024Registered scamchecker.app and rebranded from "Is It a Scam?" for cleaner search visibility, alongside scam-awareness guides and a directory of international reporting bodies.
Analytics & Growth
Feb 2025Wired up analytics, monitored organic-traffic growth, and expanded the educational guide library based on top search queries.
Community Threat Intelligence
Mar 2026Added the community reporting network on Prisma + Postgres: reports are redacted, grouped into opaque report groups, and fed back into scoring so one user's report protects the next.
Reputation Enrichment
May 2026Integrated AbuseIPDB and Google Safe Browsing as server-side enrichment — extracted indicators only, never raw content — with explicit unavailable states instead of false 'clean' results.
Hardening Pass
Jun 2026SSRF and DNS-rebinding protections on outbound URL intelligence, identity-free rate limiting, and Ed25519-signed fail-closed threat-bundle updates for the mobile engine.
iOS Companion & 1,000 Users
Jul 2026Shipped the Expo/React Native companion app to TestFlight with full engine parity, as the user base grew past 1,000 people.