We scanned our own site and found real problems. Here's everything.

Vergate Team4 min read

"Dogfood" sounds like a marketing strategy. It isn't — it's the opposite. It's finding out your own security scanner thinks your own website is insecure, five minutes after you told the internet to trust you with theirs.

That's what happened. Here's the full, unedited story, with receipts.

#The scan

On August 14, 2026, we ran Vergate's own passive engine against https://vergate.dev. Not a special "showcase" scan — the same checks every free scan runs, the same evidence packets, nothing tuned.

Result: 8 findings, every single one confirmed (likelihood: observed).

SeverityFinding
MediumMissing Strict-Transport-Security (HSTS)
MediumMissing Content-Security-Policy (CSP)
LowMissing X-Content-Type-Options
LowMissing X-Frame-Options
LowMissing Referrer-Policy
LowMissing Permissions-Policy
LowMissing Cross-Origin-Opener-Policy
LowMissing Cross-Origin-Resource-Policy

We don't just print findings — we print evidence. So we verified with our own eyes: a plain curl -I to the apex showed exactly two headers: content-type: text/html and server: Vercel. No HSTS. No CSP. No nosniff. We were the site we write blog posts warning people about. The irony was not lost on us.

#The fix

One headers() block in next.config.ts, deployed the same day:

  • Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
  • Content-Security-Policy — remote-script blocking, object-src 'none', frame-ancestors 'self' (clickjacking protection)
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: SAMEORIGIN
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy — camera, microphone, geolocation, payment, usb off
  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Resource-Policy: same-origin

Re-verified live after deploy: all 8 headers present. Zero findings remaining on the things we control.

#The finding we didn't expect: we tripped our own hosting's bot protection

Here's where it gets interesting. Re-running the scanner after the fix still showed the same findings — and "Astro" appeared in our own technology profile. We don't use Astro.

Turns out Vercel's Security Checkpoint (bot fight mode) was serving us its JS-challenge page instead of our site: x-vercel-mitigated: challenge. And it wasn't about the User-Agent — we tested systematically:

  • curl200, real site, all new headers
  • Python urllib200
  • Our scanner's HTTP client (aiohttp) → 403 checkpoint page, even with a real Chrome User-Agent
  • httpx (even forced to HTTP/1.1) → 403 checkpoint page

Vercel is fingerprinting the TLS handshake, not the browser string. Python's HTTP stack produces a TLS fingerprint its bot fight mode doesn't trust, so it challenges. The challenge page — which is Astro-built — has no security headers (it's a challenge, why would it), which is exactly what our scanner flagged. One honest observation about ourselves: the "Astro 0.4" detection was a false positive, and it was our own profiler being confused by a third party's challenge page. We traced it, we know why it happened, and we're not pretending it didn't.

This is bot protection working exactly as intended — a security company being shown the door by another security product is not a bug in either product. But it's a real operational lesson: if you protect your site with fingerprint-based bot fighting, automated scanners (including ours) will see your challenge page, not your site. Allow-list your scanner's infrastructure or use browser-grade request clients, or you'll get "findings" that are really your challenge page wearing a trench coat.

#The baseline you can hold us to

While we were at it, we recorded the performance and quality baseline (desktop Lighthouse, same tooling our /performance module uses):

  • Performance: 88/100 — LCP 1.1s (excellent), TBT 22ms (excellent), CLS 0 (perfect), FCP 0.8s. Our weak point: Speed Index 5.8s — below the fold and font rendering drag it down. We know exactly what to work on.
  • SEO: 100/100
  • Accessibility: 96/100
  • Best practices: 92/100

Real numbers, reproducible, and on the record — the same standard we hold any site we scan.

#What we learned (the actual point)

  1. Scan before you ship, not after. These headers were missing for months. A two-minute scan at launch would have caught them.
  2. Ship headers by default. If you host on a platform that doesn't add them automatically (Vercel doesn't), add them in one config block — it took us ten minutes.
  3. Re-scan after every deploy. The fix is only a fix until the next config change.
  4. Automated scanning has blind spots — document yours. We now know ours: TLS-fingerprint bot protection serves us challenge pages. Knowing that is how you avoid chasing ghosts.

Want to see if your site has the same problems we had? Our free scan runs the exact checks that caught us — no account, no credit card, results in seconds. We already know what it's like to get the email you hope you never get. Let it be you getting it from someone else's site, not yours.

Frequently asked questions

Did Vergate really find vulnerabilities on its own site?

Yes — 8 findings, every one confirmed. Most embarrassing: vergate.dev shipped no security headers at all (no HSTS, no CSP, no nosniff). We fixed all 8 the same day and re-verified them live. The full before/after is in this post.

What does the scanner see that curl doesn't?

Interesting side effect of the fix: Vercel's bot protection (Security Checkpoint) challenges Python HTTP clients by TLS fingerprint, so our own scanner was served the challenge page — not our site — during the audit. The challenge page has no security headers, which is exactly what the scanner flagged. We verified the real findings independently with curl before fixing.

What's the performance baseline?

Desktop Lighthouse: Performance 88/100 (LCP 1.1s, TBT 22ms, CLS 0 — all excellent; Speed Index 5.8s is our weak point), SEO 100, Accessibility 96, Best Practices 92.

How do I scan my own site like this?

Use the free scan on vergate.dev — no account, no credit card. It runs the same checks that found our missing headers.

Keep reading