Build better.
Debug smarter.
Deep technical articles on APIs, security, debugging, and developer tooling.
✦ AI-powered — understands natural language
Why API Key Rotation Is Harder Than It Should Be — Zero-Downtime Rotation, Secure Distribution, and the Permanent Git History Problem
GraphQL's Introspection Query Is an Attacker's Best Friend — Batching, Nested Query DoS, and Persisted Queries
GraphQL's introspection query exposes your complete schema — every type, field, and relationship — to anyone who can reach the endpoint, making it the most powerful reconnaissance tool an attacker can use against a GraphQL API. Here's batching attacks that bypass rate limiting, deeply nested queries causing 100^5 database lookups, persisted queries as a security pattern, and how to test GraphQL endpoints with a REST API checker.
Why Your RTC Chip Returns 89 When the Time Is 59 — BCD, Gray Code, and Other Number Encodings in Modern Hardware
Binary-Coded Decimal (BCD) encodes each decimal digit as a 4-bit group — which is why real-time clock chips return 0x59 to mean 59 seconds (not 89), and why hardware with BCD limits constrains values to 0-99 rather than 0-255. Here's BCD in RTC hardware and financial calculations, Gray code's one-bit-change property that prevents rotary encoder errors, and why TCP checksums use one's complement arithmetic.
Most JWT Libraries Don't Check the Audience Claim — What Gets Verified, What Doesn't, and How to Handle Revocation
JWT libraries automatically verify signatures and exp claims — but most don't check iss (issuer) or aud (audience) by default, which is why a token from service A can be used at service B if they share a signing key. Here's what each registered claim actually enforces, the three revocation approaches (short expiry + refresh tokens, jti blocklist, short expiry without refresh), and why JWT payloads are readable by anyone who holds the token.
Why \n Shows Up Literally in Your JSON Output — Escape Sequences, Encoding Layers, and How to Debug Them
JSON's \n is two characters in the file (backslash + n) that parse to one character (line feed) — and when encoding is applied in the wrong order or twice, you get literal \n in displayed output, double-escaped \\u sequences, or & where & should be. Here's the three encoding layers that commonly stack incorrectly, the specific corruption patterns and their causes, and why \/ appears in some JSON (HTML injection defence in script tags).
Why JSON Parses Differently in JavaScript, Python, and Go — Precision, Duplicates, and Parser Security
JSON's specification deliberately leaves number precision, duplicate key handling, and Unicode surrogate pairs as implementation-defined — which is why identical JSON produces different results in JavaScript (integers lose precision above 2^53), Python (arbitrary precision integers), and Go (float64 by default). Here's the parser differential security attack from duplicate keys, prototype pollution via JSON merge, and why NDJSON enables streaming gigabyte datasets with constant memory.
Using JSON Diff to Detect API Breaking Changes — Schema Diff, Merge Patch, and Contract Testing
API breaking changes — removing fields, changing types, renaming keys — are detectable by diffing JSON Schema between API versions. Here's schema-level vs instance-level JSON diff, JSON Merge Patch (RFC 7396) as a simpler alternative to JSON Patch for PATCH endpoints, why array diffing requires different algorithms than object diffing, and how contract testing uses JSON diff principles to prevent breaking API deployments in CI/CD.
SMS and TOTP Can Both Be Phished in Real Time — Here's Which MFA Methods Are Actually Phishing-Resistant
SMS OTP and TOTP are both vulnerable to real-time phishing (AiTM attacks relay codes before they expire) — hardware keys and passkeys are phishing-resistant because their response is cryptographically bound to the exact URL. Here's the MFA security spectrum from SMS to passkeys, the MFA fatigue (push bombing) attack that compromised Uber in 2022, why number matching prevents rubber-stamping push notifications, and why security questions aren't a genuine second factor.
SHA-256 Is Wrong for Passwords and bcrypt Is Wrong for File Integrity — Why Hash Function Choice Depends on Context
Hash functions serve four completely different contexts — data integrity, password storage, digital signatures, and hash tables — and each requires different properties. SHA-256 is ideal for integrity checks but catastrophically wrong for passwords (too fast); bcrypt is ideal for passwords but terrible for integrity checks (too slow). Here's why, plus SHA-2's length-extension vulnerability, BLAKE3's advantages, and the hash table DoS attack that made Python randomise its hash seeds.
HTML Encoding Doesn't Stop XSS in JavaScript Context — Why CSP Nonces Are the Missing Second Layer
HTML encoding converts < to < — but it can't protect against XSS in JavaScript contexts, where the browser parses script blocks before HTML encoding applies. Content Security Policy blocks injected scripts at the browser level, using nonces (random per-request values) or hashes to allow only legitimate inline scripts. Here's why both layers are required, how CSP nonces work, and what violation reports reveal about attacker probing.
Kubernetes CronJob vs Traditional Cron — ConcurrencyPolicy, TimeZone Support, and Why Serverless Changes Everything
Kubernetes CronJob adds concurrencyPolicy (Forbid/Allow/Replace), startingDeadlineSeconds for missed run recovery, and — since Kubernetes 1.25 — a timeZone field that classic crontab never had. Here's how cloud-native scheduling differs from traditional cron, why serverless functions with 15-minute execution limits need Step Functions for long-running jobs, how Airflow's catchup=True causes burst runs after maintenance windows, and why GitHub Actions cron is always UTC.
Why HSL's "50% Lightness" Lies — oklch, Perceptual Color Spaces, and Why They Matter for Design Systems
HSL's "50% lightness" produces visually different brightness across hues — yellow at HSL(60,100%,50%) looks far brighter than blue at HSL(240,100%,50%). oklch solves this with perceptual uniformity: equal L values produce equal apparent lightness regardless of hue. Here's how oklch works in CSS (now supported in all modern browsers), why it's the best tool for dark mode palettes, and how wide-gamut P3 colors fit in.
Argon2id Won the Password Hashing Competition — Here's Why Memory-Hardness Matters and When to Migrate From bcrypt
Argon2id won the Password Hashing Competition and is now OWASP's recommended algorithm — but its three variants (Argon2i, Argon2d, Argon2id) have different security properties, and Argon2d is specifically not suitable for password hashing despite being in the family. Here's memory-hardness and why it defeats GPU parallelism, the correct Argon2id parameters (19 MB memory, 2 iterations), when to migrate from bcrypt, and the pepper pattern for additional server-side secret protection.