QuishGuard: Isolated Headless Screenshot Sandbox

QuishGuard is a production-grade QR code anti-phishing solution designed to safeguard users and judges during hackathons. When a user interacts with a page containing a QR code, the Chrome Extension detects it, sends it to a FastAPI backend where it is decoded via OpenCV, and spins up an isolated headless Playwright browser to capture a safe screenshot. The user is redirected to a high-fidelity Next.js dashboard featuring a 3D visual preview and real-time logs tracing forensic metrics.

Monorepo Stack

  1. extension/ (Vite, React, TypeScript, Tailwind CSS v3): Manifest V3 extension featuring a DOM mutation observer, a canvas-extract heuristic scanner, floating preview badges, and right-click context menu integration.
  2. backend/ (FastAPI, Playwright, OpenCV Headless, asyncio): Asynchronous FastAPI server executing lookalike brand checks (using Levenshtein distance), Punycode/IDN homograph decoding, non-blocking DNS resolutions, and an incognito sandboxed browser session protected against SSRF.
  3. dashboard/ (Next.js App Router, Tailwind CSS v4, GSAP): Modern React dashboard featuring global stats, an active Threat Isolation Ledger, and a Threat Isolation Portal containing a live forensic terminal log stream and a 3D interactive screenshot card.

How It Works

sequenceDiagram
    participant WebPage as Web Page DOM
    participant ExtContent as Extension (content.js)
    participant ExtBG as Extension (background.js)
    participant Backend as FastAPI Backend (Port 8000)
    participant Dashboard as Next.js Dashboard (Port 3000)

    WebPage->>ExtContent: QR Image Rendered / Right-Click
    ExtContent->>ExtBG: Send Image payload (Base64 or URL)
    ExtBG->>Backend: POST /api/v1/scan (image base64)
    Note over Backend: 1. cv2.QRCodeDetector scans QR<br/>2. If found, returns scan_id immediately<br/>3. Launches background task
    Backend-->>ExtBG: Return scan_id & "scanning" status
    ExtBG->>Dashboard: Open Tab /inspect?id={scan_id}
    Note over Dashboard: Show Live Logging Terminal
    loop Poll Scan report (every 800ms)
        Dashboard->>Backend: GET /api/v1/scan/{scan_id}
        Backend-->>Dashboard: Return logs list & status
    end
    Note over Dashboard: Scan complete -> GSAP Morph Card Animation

Setup & Running Guide

Ensure you have Python 3.10+ (with uv) and Node.js 18+ installed.

1. Launch FastAPI Backend

Navigate to the backend/ directory, install dependencies, download the sandboxed Chromium engine, and start Uvicorn:

cd backend
# 1. Initialize environment and install dependencies
uv venv .venv
uv pip install -r requirements.txt
# 2. Install Playwright sandboxed browser binaries
.venv/bin/playwright install chromium
# 3. Start API server
.venv/bin/uvicorn main:app --reload --port 8000

2. Launch Next.js Dashboard

Navigate to the dashboard/ directory, install dependencies, and start the Next.js development server:

cd dashboard
npm install
npm run dev -- -p 3000

Open http://localhost:3000 to view the ledger.

3. Load the Chrome Extension

  1. Open Chrome and navigate to chrome://extensions/.
  2. Enable Developer mode (toggle in the top-right corner).
  3. Click Load unpacked and select the dist/ folder inside the extension. (Note: Run npm run build inside extension/ to compile the popup assets before loading).

Security Hardening

  • SSRF Prevention: The Playwright sandbox uses a route-interceptor to abort all requests targeted at local interfaces (127.0.0.1, localhost) or cloud metadata endpoints (169.254.169.254).
  • Incognito Contexts: The sandboxed browser runs in a fresh, isolated incognito context with zero cookies, history, or shared cache, protecting against dynamic credential-hijacking exploits.
  • Content Security Policy (CSP): The extension employs MV3 default CSP rules, preventing any inline or remote dynamic script evaluations (unsafe-eval is blocked). # QRGuard
Share this project:

Updates