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+∑​w​x), σ(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
Share this project:

Updates