security
Technical notes on web development, DevOps, and AI integration.
62 articles
- 14:00tooling
The Machine That Guards Review Claims in Commit Messages
A bash gate turns free-text Security-review claims into three machine-tested invariants on the commit-msg hook.
TL;DR: Review claims in commit messages are usually free text nobody checks, so one repo added a bash commit-msg gate turning them into machine-tested invariants. The script enforces exactly one Security-review: trailer, a fixed position above Co-Authored-By, and substance, matching "tests only" claims against a whitelist of changed paths. It's bypassable with --no-verify, but it cheaply catches honest mistakes.
#git#bash#security - 14:00security
Five Security Holes, Locked Instead of Fixed
A tests-only commit turns five weak authentication behaviors into a named inventory with owner-decision markers.
TL;DR: Instead of silently fixing five weak security behaviors, the author locked them as characterization tests with owner-decision markers. Findings include account enumeration via registration, unthrottled OTP verification, non-revoked JWTs, orphaned OTP rows, and in-memory rate-limiter state. Mapping first beats fixing from memory: each weakness becomes a prioritized decision ticket.
#testing#security#authentication - 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
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