Skip to content

Resolve request headers by presence rather than truthiness - #140

Merged
patchstackdave merged 1 commit into
mainfrom
feature/header-presence-resolution
Aug 18, 2026
Merged

Resolve request headers by presence rather than truthiness#140
patchstackdave merged 1 commit into
mainfrom
feature/header-presence-resolution

Conversation

@patchstackdave

Copy link
Copy Markdown
Contributor

What

server.HTTP_* resolved an arbitrary request header with a truthiness check, so a header present with an empty value resolved to nothing — indistinguishable from a header that was never sent.

That makes a presence-based header rule quietly incomplete. It matches every non-empty value and misses the empty one, which is the failure mode worth caring about: the rule reports as active protection while one spelling of the input walks past it. Presence checks exist precisely for inputs where no value pattern is safe to depend on, so "present but empty" is exactly the case they must not lose.

Change

The generic HTTP_* branch now resolves by presence, reading only own properties so an inherited name (constructor) cannot masquerade as a header every request carries.

The named cases — host, origin, referer, user-agent, content-type, content-length — keep value semantics on purpose. They feed matchers for which an empty string and an absent header already mean the same thing, and handing those '' instead of nothing would change comparisons that behave correctly today.

Tests

Three resolver cases: an empty header value resolves to ['']; an absent header still resolves to []; and an inherited property name resolves to [] on an empty headers object.

Full suite green (1013 tests) — nothing depended on the old behaviour.

🤖 Generated with Claude Code

The `server.HTTP_*` parameter source read an arbitrary header with a
truthiness check, so a header present with an empty value resolved to
nothing at all — indistinguishable from a header that was never sent. A
rule authored as a presence check against a header therefore matched every
non-empty value and silently missed the empty one, which is the worst kind
of gap: the rule reports as active protection while one spelling of the
input walks past it.

Resolve the generic `HTTP_*` branch by presence instead, reading only own
properties so an inherited name like `constructor` cannot masquerade as a
header that every request carries.

The named cases (host, origin, referer, user-agent, content-type,
content-length) keep value semantics deliberately: they feed matchers for
which an empty string and an absent header already mean the same thing, and
handing those an empty string instead of nothing would change comparisons
that are working correctly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderbuds

coderbuds Bot commented Aug 18, 2026

Copy link
Copy Markdown

Handles header presence accurately with clear logic and thorough tests.

🎯 Quality: 100% Elite · 📦 Size: Small

📈 This month: Your 67th PR — above team average · Averaging Excellent

See how your team is trending →

@patchstackdave

Copy link
Copy Markdown
Contributor Author

/review

@patchstackdave
patchstackdave merged commit a44cb46 into main Aug 18, 2026
6 checks passed
@patchstackdave
patchstackdave deleted the feature/header-presence-resolution branch August 18, 2026 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants