Skip to content

Harden PHP CORS proxy header filtering - #4506

Draft
brandonpayton wants to merge 2 commits into
trunkfrom
brandonpayton/cors-proxy-header-filtering-review
Draft

brandonpayton wants to merge 2 commits into
trunkfrom
brandonpayton/cors-proxy-header-filtering-review

Conversation

@brandonpayton

Copy link
Copy Markdown
Member

Motivation for the change, related issues

The PHP CORS proxy currently forwards client credentials and upstream policy headers that belong to the proxy's own connection or origin. It also emits upstream fields before seeing the complete header block, allowing a later Connection header to nominate a field that has already been queued for the client.

Strengthen this boundary while preserving streamed bodies, uploads, range requests, HEAD, redirect rewriting, Authorization opt-in, rate limiting, and the existing declared-size limits.

Implementation details

  • Filter request and response names case-insensitively, including all hop-by-hop fields and every Connection nomination. Buffer only upstream headers until the block is complete; continue streaming response bodies.
  • Consume the Authorization opt-in before removing internal control headers. Strip cookies, proxy session headers, and the deployment's explicitly trusted X-Forwarded-For and X-IP-Proxy-Type inputs from outgoing requests without changing rate-limit identity handling.
  • Remove upstream cookie, origin-policy, CORS, proxy-marker, and X-Spacefast-* / X-Stattic-* headers while preserving existing server/CDN control-header filtering. Protect proxy and deployment-owned headers, supply Vary: Origin and Cross-Origin-Resource-Policy: cross-origin, and retain the existing origin rules for CORS and the legitimate proxy marker.
  • Let cURL generate upload framing, including reconstructed multipart bodies. Replace upstream chunk framing with proxy-owned framing under PHP's built-in server, and let production web servers frame the relayed body. Suppress Content-Length whenever upstream transfer encoding is present and preserve unchanged compressed representation bytes and metadata.
  • Add unit and real-HTTP regression coverage, an optional Apache/FastCGI transport fixture, and documentation for the policy and test workflow.

Compatibility changes: The newly blocked headers are intentionally no longer forwarded. An upstream Connection nomination of a non-identity Content-Encoding now returns a clean 502 rather than relaying compressed bytes without the metadata needed to decode them.

Testing Instructions (or ideally a Blueprint)

Run the default PHPUnit and PHP built-in-server end-to-end suites:

npm exec -- nx test playground-php-cors-proxy

To also exercise Apache/FastCGI on macOS:

CORS_PROXY_TEST_HTTPD=/usr/sbin/httpd npm exec -- nx test playground-php-cors-proxy

See the proxy README for Apache module and PHP CGI overrides. The Apache fixture enables Authorization passthrough, trusts lengths from the proxy script, flushes FastCGI output, and supplies lengths for chunked uploads; these are test fixture settings, not deployment changes.

Validated locally with PHP 8.5.8 and Apache 2.4.67: 264 unit tests (365 assertions) and 527 end-to-end assertions passed. Coverage includes mixed casing, repeated and reordered Connection nominations, attempts to forge proxy-owned headers, delayed streaming, fixed-length and chunked gzip bodies, conflicting transfer framing, interim responses, ranges, HEAD, and raw/chunked/wrapped/reconstructed uploads. git diff --check also passed.

Remaining limits: Size checks retain their existing declared-length semantics rather than counting unknown-length streams. Live CDN/nginx deployment behavior has not been verified.

@coderabbitai

coderabbitai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added [Package][@wp-playground] CORS Proxy [Type] Documentation Improvements or additions to documentation labels Oct 23, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package][@wp-playground] CORS Proxy [Type] Documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant