Skip to content

Add request-scanning middleware, harden filter, rebrand to SpitFire#15

Merged
bsaranga merged 6 commits into
mainfrom
feature/middleware-and-rebrand
Jun 28, 2026
Merged

Add request-scanning middleware, harden filter, rebrand to SpitFire#15
bsaranga merged 6 commits into
mainfrom
feature/middleware-and-rebrand

Conversation

@bsaranga

Copy link
Copy Markdown
Owner

Summary

Adds a middleware-based alternative to the MVC action filter, fixes several latent crash/perf bugs in the existing filter, and rebrands the package from Zone24x7 to SpitFire.

Filter hardening

  • Skip null action arguments and null collection items instead of throwing (optional/unbound parameters no longer 500 the request)
  • Reference-based, path-scoped cycle detection so cyclic object graphs terminate instead of stack-overflowing at the default infinite recursion depth
  • Read each property value once instead of up to three GetValue calls
  • Cache PropertyInfo per type to avoid re-reflecting on every request
  • Guard AttributeRouteInfo for convention-routed controllers
  • Wire up the previously-dead WhiteListEntry.ExclusionPattern

New: request-scanning middleware

PayloadInjectionMiddleware runs before model binding and scans the raw query string and request body, so it covers minimal APIs, Razor Pages and gRPC in addition to MVC controllers.

  • AddPayloadInjectionMiddleware / UsePayloadInjectionMiddleware helpers
  • Method gating, per-path exclusions, query/body scan toggles
  • URL-decodes the query string to catch percent-encoded payloads
  • Buffers and rewinds the body so downstream endpoints can re-read it
  • Rejects bodies larger than MaxScannedBodyBytes with 413

Rebrand

  • Namespace Zone24x7PayloadExtensionFilterSpitFirePayloadExtensionFilter
  • PackageId Zone24x7.PayloadInjectionFilterSpitFire.PayloadInjectionFilter
  • Version bumped to 0.1.0

Note: the new PackageId means the next publish creates a new NuGet listing rather than versioning the old one.

Docs

  • Filter-vs-middleware comparison and middleware usage section
  • Documented the now-functional ExclusionPattern
  • Honest scope note (defense-in-depth, not a WAF / output-encoding replacement)
  • Reliability notes (cycle safety, null handling, caching)

Tests

31 → 41 passing. New tests cover null arguments, cyclic graphs, ExclusionPattern, and the full middleware surface (body/query short-circuit, body rewind, method gating, path exclusion, custom response, oversized 413).

🤖 Generated with Claude Code

saranga-coder and others added 6 commits June 28, 2026 09:57
- Skip null action arguments and null collection items instead of
  throwing (optional/unbound parameters no longer 500 the request)
- Add reference-based, path-scoped cycle detection so cyclic object
  graphs terminate instead of stack-overflowing at the default
  infinite recursion depth
- Read each property value once instead of up to three GetValue calls
- Cache PropertyInfo per type to avoid re-reflecting on every request
- Guard AttributeRouteInfo for convention-routed controllers
- Wire up the previously-dead WhiteListEntry.ExclusionPattern

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds PayloadInjectionMiddleware as an alternative to the MVC action
filter. It runs before model binding and scans the raw query string
and request body, so it covers minimal APIs, Razor Pages and gRPC in
addition to MVC controllers.

- AddPayloadInjectionMiddleware / UsePayloadInjectionMiddleware helpers
- Method gating, per-path exclusions, query/body scan toggles
- URL-decodes the query string to catch percent-encoded payloads
- Buffers and rewinds the body so downstream endpoints can re-read it
- Rejects bodies larger than MaxScannedBodyBytes with 413
- Unit tests covering body/query short-circuit, rewind, exclusions,
  custom responses and the oversized-body path

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Renames the namespace (Zone24x7PayloadExtensionFilter ->
SpitFirePayloadExtensionFilter), the NuGet PackageId
(Zone24x7.PayloadInjectionFilter -> SpitFire.PayloadInjectionFilter)
and the company metadata. Version bumped to 0.1.0 for the new
middleware feature.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add filter-vs-middleware comparison and middleware usage section
- Document the now-functional ExclusionPattern
- Add a scope note framing the library as defense-in-depth, not a
  replacement for output encoding, parameterized queries or a WAF
- Add a reliability-notes section (cycle safety, null handling, caching)
- Sync the packaged NuGet README with the root README

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The long-lived NUGET_API_KEY was revoked; nuget.org now recommends
keyless publishing via short-lived OIDC tokens.

- Use NuGet/login@v1 to exchange a GitHub OIDC token for a temporary
  API key (requires id-token: write and a NUGET_USER secret)
- Publish on push to main (merge) instead of on every pull_request,
  which previously republished the same version and failed
- Add --skip-duplicate so re-runs without a version bump don't fail
- Bump checkout/setup-dotnet to v4

Requires a one-time Trusted Publishing policy on nuget.org pointing at
this repo and the dotnet-publish.yml workflow file.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds `environment: release` to the publish job so a GitHub environment
(with optional required reviewers) governs publishing. The environment
name should also be set on the nuget.org Trusted Publishing policy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@bsaranga
bsaranga merged commit 87909c7 into main Jun 28, 2026
2 checks passed
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