Security,
with evidence.
A real review of this site's code, mapped to the OWASP Top 10. Every finding links to the exact commit that fixed it - verifiable in the repo's public history, not a promise.
This site runs its own security observability engine (a "micro-SIEM"): an OWASP-aligned threat classifier runs in the middleware on every request, decoy endpoints confirm malicious intent, and an hourly cron applies temporary blocks and statistically detects anomalies (z-score over a 30-day baseline). The numbers below are real aggregates from the last 30 days.
Breakdown by category (OWASP)
- Secrets/config probing396
- Decoy endpoint touched325
- Blocked repeat offender47
- CMS/panel reconnaissance35
- Path traversal / LFI16
- cuenta_cobro2
- Offensive bot2
- csp_violation1
Geographic origin
- US455
- NL44
- SG36
- FR36
- DE29
- BR28
Daily trend (14 days)
How it works (4 layers)
- 01Automatic DDoS mitigation and the platform firewall (Vercel).
- 02A custom classifier in the middleware: OWASP signatures, two-layer durable rate limiting, IP blocking.
- 03Logging of every hostile event (with burst deduplication) and decoy endpoints that confirm malicious intent.
- 04Hourly cron: aggregates, detects statistical anomalies, auto-blocks repeat offenders, and alerts.
Pipeline SLO targets
- Overhead added per request (p99)≤ 5 ms
- Detection → automatic block≤ 60 min
- Detection → alert (critical)≤ 60 s
- False-positive blocks< 0.1%
- Raw event retention90 days
By design, this page never shows full IPs, exact detection rule names, or which routes are decoy endpoints - that would hand an attacker the playbook.
Stored XSS via unvalidated file extension
highA03:2021 · Injectionsrc/pages/api/admin/upload.tsThe certificate upload endpoint derived the final file extension from the client-supplied filename, and only validated the MIME type declared by the client itself (easily forged). A file uploaded as "foo.html" with a fake Content-Type ended up served as HTML from /assets/certs. SVG was also on the allowed-types list, and an SVG can contain an executable <script>.
The extension is now derived from a fixed MIME → extension map, never from the filename. SVG was removed from the allowed types.
Contact form with no rate limit or validation
mediumA04:2021 · Insecure Designsrc/pages/api/contact.tsThe public contact endpoint accepted unlimited inserts into the database with no rate limit, no email format validation, no field length limits, and malformed JSON produced an unhandled 500 error.
The project's existing rate limiter was applied (5 submissions/min per IP), along with email format validation, per-field length limits, and explicit handling of invalid JSON.
Sessions without a login claim bypassed the allowlist
mediumA01:2021 · Broken Access Controlsrc/middleware.tsThe middleware only revalidated the GitHub allowlist when the session carried the "login" claim. A session without that claim passed the check by default instead of being rejected.
The admin gate now requires the claim on every session: without a valid login on the allowlist, the response is 403, no exceptions.
CSP and HSTS were missing from responses
mediumA05:2021 · Security Misconfigurationsrc/middleware.tsThe middleware already set several security headers (nosniff, Referrer-Policy, X-Frame-Options on admin) but included no Content-Security-Policy or Strict-Transport-Security on any route.
A restrictive CSP (default-src self, frame-ancestors none) and HSTS with preload were added to every response, public and admin alike.
Verified payment webhooks
The Wompi event receiver verifies the HMAC signature before processing any event, rejects events older than 6 hours (anti-replay), and validates that the amount/currency match the expected payment before applying a state transition.
Secrets encrypted at rest
The credentials vault encrypts every value with AES-256-GCM (authenticated encryption) before writing it to the database. The key lives only in the server environment, never in the database or in backups.
Defense in depth on /admin
Authorization is revalidated against the allowlist both in the login callback and in the middleware, on every request - logging in once is not enough.
Parameterized queries
All data access goes through Drizzle ORM with parameterized queries; there is no SQL string interpolation anywhere in the project.
The review covered authentication and access control, file uploads, public endpoints, secret handling, payment webhooks, and response headers - this repository's real code, not a theoretical exercise.
Every finding was classified against the OWASP Top 10 (2021), fixed in a dedicated commit, and verified with the test suite and a full build before merging.
This page is updated every time an audit finds or fixes something new. What you see here is the real state of the code in production.