You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GET guestbook returns only createdAt + message; stored IP is sha-256 hashed
Threat actors
Actor
Target
Vector
Outcome
Random bot
any POST
cross-site form/fetch
blocked by guardOrigin (403)
Spammer
guestbook
scripted posts
blocked by token + honeypot + rate limit
Flooder
chat (Gemini quota)
rapid same-site requests
rate limited (10/min/IP) + 60/min global budget across all visitors
Curious dev
endpoints
manual probing
sees only public data; no stack traces, no PII
Attacker with real browsers
any write
distributed, one request per IP
residual risk — no auth, by design (chat is covered by the 60/min global budget)
Known limitations (deliberate tradeoffs)
Rate limiter is in-memory per serverless instance — resets on cold start.
The chat endpoint adds a global 60/min budget across all visitors, so a
distributed flood can no longer drain the AI quota on a single instance.
Ceiling: floods that outlive instance recycling. Upgrade path: Redis-backed
limiter if the site ever gets real traffic.
CSRF token is derivable (hour slice + public base URL) — cosmetic only.
The real protection is guardOrigin: browsers enforce the Origin header,
which cross-site requests cannot forge.
Write endpoints have no authentication — the guestbook is anonymous by
design. Anything public can be written by anyone.
Gemini prompt injection can at most leak the public profile (the system
prompt contains no secrets).
Browser APIs (mic, Bluetooth, battery, screen-share) are permission-gated
by the browser and guarded with fallbacks.
Not implemented (YAGNI)
API keys, Redis rate limiting, per-user auth, WAF rules — all would break the
anonymous guestbook or add cost without protecting anything sensitive. Add
when the site outgrows "personal linktree".