Skip to content

feat: block scanner junk at the nginx edge - #72

Draft
mroderick wants to merge 1 commit into
mainfrom
feature/scanner-junk-edge-block
Draft

mroderick wants to merge 1 commit into
mainfrom
feature/scanner-junk-edge-block

Conversation

@mroderick

Copy link
Copy Markdown
Collaborator

Block scanner junk at the nginx edge so it never reaches the auth app.

The planner gets the same treatment in codebar/planner#2884; this applies the identical rules to the auth nginx config. Probes have not targeted the auth host in the log archive yet, but wordlists don't discriminate, and the config already carries bad-bot and rate-limit guards. None of the blocked patterns are valid auth routes, so the block is behaviour-preserving.

Changes

Two regex locations in config/nginx.conf.erb, ahead of the location / proxy:

  • Sensitive or unknown file extensions (nested paths included), excluding the /static asset dir
  • Extension-less probes seen in the log archive: id_rsa-style key names, wp-* paths, /__vite_rsc_findSourceMapURL, the debug-trigger probe, Dockerfile, __debug__, userfiles, backup, private[-_]key

New CI job nginx-edge-config renders the ERB, runs nginx -t, and asserts a curl matrix: scanner probes 404 at the edge, /static assets and app routes pass through. Curls use a browser user-agent because the existing bad-bot map 444s curl. The e2e suite bypasses nginx entirely, so nothing previously verified this config.

Verification

  • Rendered config passes nginx -t
  • Probe/passthrough matrix verified against a live nginx:alpine container, sized under the existing limit_req burst
  • prettier:check clean
Review notes
  • The /static exclusion is a hand-maintained allowlist. A new public asset directory outside /static would silently 404 at the edge; the CI matrix is the guard, so keep both in sync.
  • The extension/probe lists are duplicated between this config and the planner's (feat: block scanner junk at the nginx edge planner#2884) with no shared source; keep them in sync by review until a shared source exists.
  • This blocklist is noise reduction, not a security boundary: probes avoiding the listed patterns (e.g. /api/auth/* paths) still reach Better Auth unchanged.
  • Pre-existing behaviour, unchanged by this PR: the bad-bot map and rate limit apply to all requests; edge 404s skip the rate limiter because they return in the rewrite phase.

Scanner probes targeting the planner (SSH keys, cloud configs, .env
files, Vite RSC source-map probing) also hit this app; none are valid
routes. Return 404 at nginx instead of forwarding to Hono, alongside
the existing bad-bot and rate-limit guards.

Two regex locations in config/nginx.conf.erb:

- sensitive or unknown file extensions (nested paths included),
  excluding the /static asset dir
- extension-less probes seen in the canonical log archive (id_rsa-
  style key names, wp-* paths, /__vite_rsc_findSourceMapURL, the
  debug-trigger path)

Code review findings shaped the final rules: the .env branch missed
.env.local and .env.production variants (fixed), and the e2e suite
bypasses nginx entirely, so nothing verified this config (addressed
with a new CI job below). Curls in the CI job use a browser user-agent
because the existing bad-bot map 444s curl.

New nginx CI job renders the ERB, runs nginx -t, and asserts a curl
matrix: scanner probes 404 at the edge, /static assets and app routes
pass through.

Verified against a live nginx:alpine container: the full probe and
passthrough matrix passes, and prettier:check is clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant