---
name: vibe-check-scan
version: 1.0.0
emoji: 🔍
keywords: [security, scanner, headers, tls, cors, api-surface, web-security, cve]
description: Use when the user wants to scan a website for security issues, check HTTP headers, TLS/SSL configuration, CORS policy, or API surface exposure.
---

# Vibe Check Scan

Free passive web security scanner. Returns an A–F grade with per-module findings. No auth required.

## When to use

- User asks to scan a URL for security issues
- User wants to check if a site has proper security headers (CSP, HSTS, etc.)
- User asks about TLS/SSL certificate or protocol version
- User wants to check CORS policy on a site
- User wants to find exposed API endpoints or sensitive files
- User asks about CVE-2025-55182, CVE-2025-55183, or CVE-2025-55184 (React RSC vulnerabilities)

## When NOT to use

- User asks general security questions answerable from your knowledge
- User wants active penetration testing, fuzzing, or credential testing (this tool is passive only)
- User wants to scan a private/internal IP or localhost
- You already have the scan result in context — answer from context, do not re-scan

## Scanning workflow

Scanning is asynchronous. Prefer this 2-step flow:

| Step | Action | Wait? |
|------|--------|-------|
| 1 | POST /api/scan/start with { "url": "..." } | No — returns scanId immediately |
| 2 | GET /api/scan/status?id={scanId}&format=agent | Poll every 2–3s until top-level status becomes "completed" or "error" |

When the scan finishes, the final status response includes a `result` payload so agents do not need a separate result fetch.

Optional:
- GET /api/scan/result?id={scanId} for the full JSON report
- GET /api/scan/result?id={scanId}&format=summary for condensed JSON
- GET /api/scan/result?id={scanId}&format=agent for message-ready JSON (`text` + `markdown`)
- GET /api/scan/result?id={scanId}&format=text for plain text
- GET /api/scan/result?id={scanId}&format=markdown for Markdown suitable for Telegram/WhatsApp-style delivery

## Terminology

| API term | Meaning |
|----------|---------|
| `scanId` | 32-char hex identifier for a scan session |
| `overallGrade` | A–F letter grade (A = 90–100, F = <60) |
| `overallScore` | 0–100 weighted score across four weighted modules |
| `modules` | headers (35%), tls (30%), cors (20%), apiSurface (15%) |
| `probes` | Individual CORS test requests sent to the target |
| `APISurfaceFinding` | Structured finding with `kind`, `category`, `path`, `status`, and `reason` |
| `confirmedExposure` | Path returned readable content that should be restricted — counts against score |
| `protectedSurface` | Path exists but access is correctly blocked (401/403) — no score penalty |
| `expectedPublicEndpoint` | Health, discovery, or metadata path — intentionally public, no score penalty |
| `hardeningOpportunity` | Not exposed but could be hardened further — informational only |

## Interpreting results

When a user asks about their results, explain from the data already in context — do not re-scan.

- **Grade is a weighted average.** Headers (35%) and TLS (30%) dominate. A low apiSurface score rarely drives the overall grade below B on its own.
- **Only `confirmedExposure` findings cost points.** `protectedSurface` and `expectedPublicEndpoint` findings are informational. Reassure the user if their protected routes and blocked file probes show up — that means their access controls are working.
- **Priority order:** sensitive file exposures → missing HSTS → missing CSP → weak TLS → CORS wildcards → unprotected API data → remaining lower-priority headers. Missing X-Frame-Options or Permissions-Policy alone is usually a hardening opportunity, not a serious incident.
- **For in-depth remediation guidance**, fetch `https://vibecheckscan.com/api/agent/interpret` once. It contains per-finding fix instructions, the full category reference, and answers to common user questions.

## Error recovery

| Code | Meaning | What to do |
|------|---------|-----------|
| `missing_url` | No URL in request body | Add "url" field |
| `invalid_url` | URL failed validation | Check format (must be http/https), ensure host is public |
| `rate_limit_exceeded` | Too many requests | Wait for Retry-After seconds, then retry |
| `scan_not_found` | Scan expired or invalid ID, or poll reached a different stateless instance | Reuse session affinity if available or start a new scan; production fix is shared storage |
| `invalid_scan_id` | Bad scanId format | Use exact scanId from start_scan response |

## Rate limits

- 5 scans per IP per minute for POST /api/scan/start
- 100 requests per IP per minute for status/result polling
- 429 responses include `Retry-After` header in seconds

## Machine contracts

| Resource | URL |
|----------|-----|
| Capability registry | https://vibecheckscan.com/api/agent/capabilities |
| OpenAPI 3.1 spec | https://vibecheckscan.com/api/openapi.json |
| Agent card | https://vibecheckscan.com/api/agent/card |
| Interpret guide | https://vibecheckscan.com/api/agent/interpret |
