security
Technical notes on web development, DevOps, and AI integration.
54 articles
- 18:56security
The ZAP Baseline: Zero Failures Is Not the Number That Matters
A passive ZAP baseline before a QA backfill wave: zero FAIL, four WARN, and a rule-level delta table proving the new OAuth surface added no alerts.
TL;DR: The ZAP baseline rerun after adding Google OAuth came back clean: zero FAIL, four WARN, 57 PASS. More convincing, every rule-level count versus the prior baseline dropped or stayed flat, verified from the JSON artifact. Since the scan was passive and unauthenticated, these results cover only public pages; admin and API surfaces need their own session.
#zap#security-testing#owasp - 14:45ai
Where MCP Config Lives: User or Project Scope
Where MCP configuration belongs: workspace files travel with the repo and get team review, user profiles stay personal and skip review entirely.
#mcp#vscode#security - 14:45ai
When to Retire an AI Agent from Your Workflow
An objective evaluation framework for retiring AI agents: OWASP excessive agency root causes, MCP authorization audits, and operational retirement signals.
#ai#security#mcp - 04:43backend
The Client IP You Can Actually Trust
The first X-Forwarded-For entry is attacker-controlled. Which address behind Cloudflare and nginx actually deserves a rate limiter's trust.
TL;DR: A burst of password guesses on an admin login exposed a flaw: the rate limiter trusted an attacker-controlled X-Forwarded-For entry. The fix prefers Cloudflare's CF-Connecting-IP header, then the last proxy entry, then X-Real-IP, and finally the raw connection address. Per-account keys pairing IP with email, 429 responses with Retry-After, and bounded memory keep the limiter effective.
#go#security#nginx - 01:58security
The Hostname DNS Never Listed
Certificate Transparency logs publish every TLS certificate, SAN list included. Hostnames can surface before DNS ever shows them.
TL;DR: A TLS scan uncovered a hidden staging hostname via the certificate's SAN list, invisible to DNS enumeration. That's because Certificate Transparency makes every publicly-trusted issuance public and permanent, sometimes before DNS records or deployment exist. This cuts both ways: defenders spot unauthorized certificates while attackers discover hostnames early, though a logged name proves intent, not a live service.
#security#pki#certificate-transparency - 01:03security
Reading a Tech Stack from Public Signals
Passive recon: map a stack from subdomains, archived URLs, TXT records, MX, nameservers, and secret scans without sending one packet to the target.
TL;DR: Passive recon maps a domain's tech stack from public data alone—DNS, subdomains, old URLs, headers—without touching the target. The catch: signals mislead easily, since verification tokens don't prove actual usage and Cloudflare headers matter less than nameserver records. Found secrets? Stop at discovery—validation crosses into active territory, so report through official disclosure channels.
#security#dns#tooling - 17:58backend
An Honest Contract for Batch Ingest Endpoints
One success number for a whole batch hides partial failure. Per-item created/updated/unchanged/rejected status makes it visible.
TL;DR: The new POST endpoint replaces a single batch status with per-item outcomes plus a summary so partial failures are visible. Guards cap payload size and item count, rate-limit per source, and fail closed with proper status codes including constant-time auth. Each item is marked created, updated, unchanged or rejected via a content hash, with an audit row for every request.
#fastapi#api#rest-api - 23:55security
A Rate Limit Alone Was Not Enough for This Login Endpoint
Sliding window dual keying plus dummy-hash timing equalization: two separate defenses for one login endpoint.
TL;DR: A live smoke test confirmed the login rate limiter kicks in with HTTP 429 and a Retry-After header on the eleventh attempt per minute. The real fix pairs that throttling with timing equalization, running bcrypt against a dummy hash so response speed never reveals whether an account exists. Docs endpoints are now dev-only, and duplicate registrations return 409.
#security#fastapi#python - 17:43backend
A FastAPI Skeleton of Layer Contracts, Not Empty Folders
Four folders with empty __init__.py files carry real contracts: layer boundaries, a unit of work per request, JWT tenant claims, and the 72-byte bcrypt gate.
TL;DR: Four seemingly empty folders establish layered contracts in a FastAPI skeleton, keeping business logic, technical details, and HTTP translation cleanly separated. A yield-based dependency handles transactions per request, committing only on success so multi-table use cases stay atomic. Multi-tenancy rides in JWT claims, bcrypt limits get enforced at the validation gate, and swappable signal sources await future needs.
#fastapi#python#jwt