Inspiration
Phishing and “dark UI” tricks still cause most everyday account takeovers. Many tools depend on cloud lookups or telemetry. I wanted a private-by-design, explainable, and fast solution that teaches users why a page is risky, right when it matters.
What it does
Analyzes pages locally and assigns a risk score with a ✅/⚠️/⛔ badge.
Explains the score in plain English (e.g., “external form action,” “suspicious TLD,” “urgent language”).
Let's users adjust thresholds and whitelist trusted domains, no central server, no data sharing.
How we built it
Stack: Chrome Extension (Manifest V3), JS/HTML/CSS only—no frameworks, no network calls.
Architecture:
Content script extracts URL/DOM features and renders the badge.
Lightweight ML + heuristics compute the risk score.
Popup shows explanations + controls; Options manage whitelist & thresholds.
Storage: chrome.storage.local for all settings (fully local).
Model: I used a tiny logistic regression over interpretable features score=100⋅σ(b+∑wx), σ(z)=1/(1+e^(−z)) Features include:
URL: IP-host, @ in URL, punycode, suspicious TLDs (e.g., .zip, .xyz), long/ hyphenated host, HTTP vs HTTPS.
DOM: presence of password forms, external form actions, hidden inputs, iframes, disabled right-click, urgency keywords (e.g., “verify,” “suspend,” “immediately”).
Weights were tuned for high precision on clear phishing patterns and early caution on borderline cases.
Explainability: After scoring, the extension lists the feature contributions (“why” items) so users learn safer habits while browsing.
Demo & Evaluation
legit1.html: Standard same-origin form (no passwords, no hidden inputs, no iframes, no urgency language) → low score.
phish1.html: External form action, hidden inputs, iframes, disabled right-click, urgency language, and a punycode look-alike link → high score with multiple red flags explained.
Challenges we ran into
Balancing precision vs. recall: Too sensitive → noisy; too lax → missed risks. Threshold tuning + feature caps (e.g., limit iframe/keyword counts) helped.
Explainability without clutter: Kept explanations concise and prioritized the most meaningful signals.
Manifest V3 constraints: Ensured everything runs smoothly with a service worker background and content scripts.
Accomplishments that we're proud of
Fully on-device detection, no telemetry, no blocklist dependency.
Human-readable rationales that improve user intuition, not just a red light.
A tiny footprint that feels native and snappy.
What we learned
Small, interpretable models can deliver real value when paired with good features and UX.
Many “dark patterns” are detectable via simple, robust signals (cross-origin form posts, urgency phrasing, off-screen/hidden elements).
What's next for WebShield 911
Firefox (MV3) port.
Sector-tuned packs (banking, commerce) with domain-specific weights.
Dark-pattern catalog (countdown timers, deceptive consent banners) with clearer guidance.
Optional local TF.js model swap while preserving explainability.
Built With
- chrome.action
- chrome.storage
- chrome.storage.local
- content-scripts
- css3-platform:-chrome-extension-manifest-v3-(chromium-based-browsers)-browser-apis:-chrome.scripting
- html5
- in-page-badge-overlay-dev/tools:-vs-code
- javascript
- languages:-javascript-(es2020+)
- local
- marp-for-slides
- no-cloud-services-(fully-local)-packaging/config:-json-manifest
- no-telemetry
- popup/options-pages
- python-m-http.server-for-local-demo-hosting-data/privacy:-no-databases
- service-worker-background-core-tech:-on-device-logistic-regression-(vanilla-js)
- storage
- url-&-dom-feature-extraction-ui:-plain-html/css-(no-frameworks)
- via
Log in or sign up for Devpost to join the conversation.