aboutsummaryrefslogtreecommitdiffstats
path: root/AGENTS.md
diff options
context:
space:
mode:
authorgrm <grm@eyesin.space>2026-09-18 13:46:11 +0300
committergrm <grm@eyesin.space>2026-09-18 13:46:11 +0300
commitf8d90e3d80ec798689be5fdf792e6c1401ad748f (patch)
tree80e37791696168eb09ccccdec37bfc0f75e4f52d /AGENTS.md
parent90578f02d851ab4e28a066404fbcf4be6a0ed9a7 (diff)
downloadblogspace-f8d90e3d80ec798689be5fdf792e6c1401ad748f.tar.gz
blogspace-f8d90e3d80ec798689be5fdf792e6c1401ad748f.tar.bz2
blogspace-f8d90e3d80ec798689be5fdf792e6c1401ad748f.zip
Security: Throttle login attempts with a per-address, per-account token bucket
Nothing stopped a bot from trying passwords against /webadmin as fast as bcrypt would go. A small in-memory limiter (stdlib only, one process) now refuses a login with 429 once an address, or an account, has made ten attempts, and lets one more through every six seconds; keying on both means many addresses guessing one account are throttled too. Refusals are logged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'AGENTS.md')
-rw-r--r--AGENTS.md5
1 files changed, 5 insertions, 0 deletions
diff --git a/AGENTS.md b/AGENTS.md
index 6d7b355..577ab82 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -132,6 +132,11 @@ internal/web/ server.go (host router, middleware, render helpers)
limits for the Files page's multi-upload (`maxUploadFiles` = 10). Errors
from `guardPOST` go through `s.fail`, which answers JSON when the request
has `Accept: application/json` (the upload scripts).
+- **Hardening** (`web/ratelimit.go`): a per-key token bucket throttles the
+ anonymous endpoints worth abusing — `loginLimit` on `POST /webadmin`, keyed
+ by client address *and* by lowercased username (10 at once, then 10 a
+ minute each), answered with 429 by `s.throttle` and a log line. Flood
+ control for everything else stays at the reverse proxy (`limit_req`).
- **Templates**: each page file is parsed together with its layout
(`layouts/dashboard.html` or `layouts/blog.html` for `blog/*`) and all
`partials/*.html`. Page files define `content` (and optionally `title`).