DEV Community

Paras Tejpal
Paras Tejpal

Posted on

I Built a Free API That Detects Phishing Sites Using AI Vision — And It Catches Prompt Injection Too

Most phishing detection APIs check URL reputation databases. The problem? Brand new phishing sites aren't in any database yet. And a growing new category of attack — prompt injection — doesn't look suspicious to any URL scanner at all.

I built PhishVision to solve both.

What is PhishVision?

PhishVision is a REST API that:

  1. Launches a real headless Chromium browser and visits the URL
  2. Captures a screenshot (JPEG)
  3. Extracts all visible and hidden page text
  4. Sends both to GPT-4o with a forensic analyst prompt
  5. Returns a structured JSON verdict

Because it uses visual analysis alongside text extraction, it catches brand impersonation and stealth payloads instantly, even on 5-minute-old domains.


🛠️ The Tech Stack

I built PhishVision using:

  • Node.js (TypeScript): Clean, asynchronous backend structure
  • Express: REST API routing
  • Playwright: Controls headless browser instances and handles security checks
  • Cascading API Fallbacks: Automatically rotates between 6 API keys (Groq, Gemini, GitHub Models, OpenRouter, DeepSeek, and Mistral) to keep execution entirely free.

💻 Code Example: Running a Forensic Scan

Here is a simple example of sending a POST request to analyze a suspicious login URL:


bash
curl -X POST https://opticparse-1opticparse-node-sg.onrender.com/api/phish-detect \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://suspicious-microsoft-portal.com" }'
{
  "verdict": "malicious",
  "confidence_score_percentage": 97,
  "impersonated_brand": "Microsoft",
  "threat_type": "brand_impersonation",
  "visual_anomalies_detected": [
    "Pixelated logo in layout",
    "Mismatched domain url"
  ],
  "hidden_payload_detected": null,
  "javascript_threats": [
    "Stealth keylogger listening to login forms"
  ],
  "redirect_risk": "Redirected through 3 domain hops"
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)