[CORS Proxy] Fix FirewallInterferenceError on local dev server#3353
Merged
[CORS Proxy] Fix FirewallInterferenceError on local dev server#3353
Conversation
WordPress Playground runs inside a sandboxed iframe, which makes the browser send `Origin: null` (the literal string) with every cross-origin request. The CORS proxy didn't recognize this as a valid origin, so it omitted all CORS response headers including X-Playground-Cors-Proxy. The client then threw FirewallInterferenceError, mistaking the missing header for network firewall interference. The fix adds 'null' to the default supported_origins list, alongside the existing localhost and playground.wordpress.net entries. This keeps it configurable – production deployments that override the list via PLAYGROUND_CORS_PROXY_SUPPORTED_ORIGINS must include 'null' explicitly. Also enables the existing test suite (test.sh was a no-op before) and adds e2e tests that start the actual PHP proxy server, send requests with various Origin headers, and verify CORS behavior end-to-end. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Updates the PHP CORS proxy to treat the literal Origin: null (from sandboxed iframes) as an allowed origin, preventing missing CORS/identification headers and avoiding client-side FirewallInterferenceErrors. Adds/activates unit + end-to-end tests to validate Origin handling via real HTTP requests against a live PHP built-in server.
Changes:
- Allow
'null'inshould_respond_with_cors_headers()default supported origins. - Add e2e harness that starts an upstream mock + the proxy and asserts on CORS headers end-to-end.
- Enable
test.shto run PHPUnit + e2e tests.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/playground/php-cors-proxy/cors-proxy-functions.php | Accepts 'null' origin; makes is_private_ip() overridable for test routing. |
| packages/playground/php-cors-proxy/tests/ProxyFunctionsTests.php | Adds unit coverage for should_respond_with_cors_headers() including 'null'. |
| packages/playground/php-cors-proxy/tests/e2e/cors-proxy-e2e-test.php | New e2e test runner that boots servers and validates CORS headers. |
| packages/playground/php-cors-proxy/tests/e2e/proxy-test-router.php | Test router to override private-IP blocking while exercising the real proxy. |
| packages/playground/php-cors-proxy/tests/e2e/upstream-mock-router.php | Mock upstream endpoints for proxy e2e runs. |
| packages/playground/php-cors-proxy/test.sh | Turns test script into an actual runner for unit + e2e. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
4 tasks
In production, the CORS proxy lives at a different domain (wordpress-playground-cors-proxy.net), so the browser always sends an Origin header on cross-origin requests. In dev, the CORS proxy is accessed via a same-origin Vite proxy (/cors-proxy/), so the browser doesn't send an Origin header at all. Without a recognized Origin, the proxy omitted the X-Playground-Cors-Proxy marker, causing the client to throw FirewallInterferenceError. Detect the PHP built-in dev server (cli-server SAPI) and accept every origin in that context. Use Access-Control-Allow-Origin: * as fallback when no Origin header is present. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
15330ad to
dbe2966
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What it does
Fixes
FirewallInterferenceErrorwhen using the CORS proxy during local development.Rationale
In production, the CORS proxy lives at
https://wordpress-playground-cors-proxy.net— a different domain. The browser sendsOrigin: https://playground.wordpress.neton every cross-origin request, the proxy recognizes it, and includes theX-Playground-Cors-Proxymarker header.In dev, the CORS proxy is exposed at
/cors-proxy/on the same Vite dev server (127.0.0.1:4400). The browser treats this as a same-origin request and doesn't send anOriginheader at all. Without a recognized origin,should_respond_with_cors_headers()returnedfalse, theX-Playground-Cors-Proxymarker was omitted, andfetchWithCorsProxythrewFirewallInterferenceError.Making the proxy cross-origin in dev isn't an option — the Vite proxy exists to avoid Chrome's Private Network Access restrictions.
Implementation
Adds
is_local_dev_server()which checksphp_sapi_name() === 'cli-server'. Bothshould_respond_with_cors_headers()and theAccess-Control-Allow-Originheader use it: the dev server accepts any origin, and falls back to*when noOriginheader is present. Production behavior is unchanged — unknown or missing origins are still rejected.Also wraps
is_private_ip()infunction_exists()so e2e tests can override it to allow localhost upstream connections, and enablestest.shto actually run the test suite.Testing instructions
cd packages/playground/php-cors-proxy bash test.sh