Know before you click.
A defensive, server-side URL intelligence tool that audits suspicious links, explains the evidence behind a risk score, and keeps the browser away from the target site.
PhishGuard is designed for safe, explainable phishing triage. The submitted URL is sent to the PhishGuard server; the user's browser does not contact the target. The server performs bounded checks, renders pages in an isolated headless Chromium context, and combines deterministic evidence with an optional Gemini supplemental assessment.
| Layer | Purpose |
|---|---|
| URL safety | Normalizes HTTP(S) URLs, blocks credentials, private/local targets, non-standard ports, and self-targets. |
| Network audit | Follows redirects within a bounded hop limit and inspects HTTP status, TLS, security headers, and domain-age data when available. |
| Headless audit | Uses Chromium to inspect rendered DOM, forms, iframes, links, scripts, console errors, and page metadata without submitting credentials or executing target actions. |
| Risk engine | Produces a 0–100 score with Safe, Suspicious, or Dangerous classification and explainable reasons. |
| Gemini supplement | Uses gemini-3.1-flash-lite with minimal thinking to interpret server-collected context. Gemini never replaces the deterministic local verdict. |
| Persistence | Stores scan history and enforces expiry-cleaned, database-backed IP rate limiting. |
PhishGuard is not a credential tester, crawler, or exploitation tool. It does not submit forms, transmit browser credentials, download target files, or allow arbitrary browser-to-target communication. Redirects, private addresses, popups, downloads, and browser lifecycle failures are bounded and sanitized.
Important: A score is an explainable triage signal, not a guarantee of safety. Treat high-risk results seriously and verify important links through an independent trusted channel.
Every completed scan returns a deterministic local assessment. When configured, Gemini appears as a separate supplemental provider result with its own status, verdict, confidence, summary, and findings.
local audit → primary verdict and score
Gemini → bounded supplemental interpretation
fallback → local verdict remains available if Gemini is disabled, slow, malformed, or unavailable
The first-party REST contract is documented in SCAN_API.md. The main endpoint is:
POST /api/scan
Content-Type: application/json
{"url":"https://example.com/login/verify-account"}The React client uses the equivalent typed tRPC procedure at scan.analyze; both paths use the same shared scan service.
| Area | Stack |
|---|---|
| Frontend | React 19, Vite, Tailwind CSS 4, shadcn-style UI components |
| Backend | Express 4, tRPC 11, TypeScript |
| Browser audit | Playwright Core with Chromium in the production container |
| Persistence | Drizzle ORM with MySQL/TiDB-compatible database |
| AI supplement | Google Gemini Interactions API, gemini-3.1-flash-lite |
| Testing | Vitest, headless lifecycle tests, REST integration tests, tRPC/REST parity tests |
The project uses Node.js and pnpm. Install dependencies, provide the required server environment, and start the development server:
pnpm install
pnpm devFor a production build:
pnpm check
pnpm test
pnpm build
pnpm startThe optional Gemini layer requires a backend-only GEMINI_API_KEY. It is safe to leave the key unset: deterministic server-side analysis continues to work and the UI reports Gemini as disabled. Never expose the key in a browser bundle or commit it to the repository.
The current release has a comprehensive Vitest suite covering URL safety, scoring, redirects, timeouts, headless isolation, popup/download handling, rate limiting, Gemini success and fallback states, REST integration, and tRPC/REST contract parity. The latest verification completed with 30 passing tests, TypeScript validation, and a production build.
A controlled harmless test using https://httpbin.org/anything/login/verify-account returned a Suspicious result in the live preview. The path contains phishing-like terms, but the domain is a testing service; no active phishing site was used.
client/ React application and result UI
server/ URL analysis, headless audit, Gemini adapter, routers, and HTTP API
drizzle/ Database schema and migrations
shared/ Shared types and constants
docs/ Release notes and repository artwork
SCAN_API.md First-party REST API contract
Dockerfile Chromium-ready production container configuration
phishguard-7buolmv8.manus.space
This project is released under the MIT License. See package.json for the project license declaration.
Use PhishGuard only for defensive analysis of URLs you are authorized to inspect. Do not use it to collect credentials, evade access controls, or probe systems without permission.