Skip to content

Fix #4130: Remove allowedMethods gate from non-preflight CORS actual requests - #4171

Merged
987Nabil merged 1 commit into
mainfrom
fix-4130-cors-non-preflight
Sep 11, 2026
Merged

Fix #4130: Remove allowedMethods gate from non-preflight CORS actual requests#4171
987Nabil merged 1 commit into
mainfrom
fix-4130-cors-non-preflight

Conversation

@987Nabil

Copy link
Copy Markdown
Contributor

Fixes #4130.\n\n## Summary\nIn Middleware.cors(...), the non-preflight (actual request) handler in the HandlerAspect was still doing:\nscala\ncase Some(allowOrigin) if config.allowedMethods.contains(request.method) =>\n ...\ncase _ =>\n 403 Forbidden\n\n\nPer the Fetch spec (and the library's own docs), the allowedMethods / Access-Control-Allow-Methods check is preflight-only. The browser already enforces the method during preflight. For the actual request the server should only gate on origin (and emit the CORS headers if allowed).\n\nThis caused 403s on valid post-preflight requests (e.g. PATCH/DELETE when not explicitly listed) even after a successful preflight.\n\n## Fix\nNon-preflight path now only checks origin:\nscala\ncase Some(allowOrigin) =>\n ZIO.succeed((corsHeaders(allowOrigin, acrhHeader, isPreflight = false), (request, ())))\n\n(The 403 case is now only for disallowed origin.)\n\nThe preflight optionsRoute + all other CORS logic (header prebuilding, etc.) is untouched.\n\n(Verified on main + matches the original report + spec reference.)

Copilot AI review requested due to automatic review settings June 19, 2026 18:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.

Removes the allowedMethods check from non-preflight (actual) CORS requests so that only preflight enforces allowed methods, avoiding incorrect 403 responses after a successful preflight.

Changes:

  • Update non-preflight CORS path to gate only on allowedOrigin, not allowedMethods.
  • Keep the 403 Forbidden response exclusively for disallowed origins on actual requests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@CLAassistant

CLAassistant commented Jun 19, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@netlify

netlify Bot commented Jun 19, 2026

Copy link
Copy Markdown

Deploy Preview for zio-http ready!

Name Link
🔨 Latest commit 332f601
🔍 Latest deploy log https://app.netlify.com/projects/zio-http/deploys/6aa3a69ac37c480008d8d080
😎 Deploy Preview https://deploy-preview-4171--zio-http.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

…requests

Per Fetch spec, the allowedMethods check (and resulting 403) is only for preflight. For actual cross-origin requests, only the origin should be checked.

The previous code re-applied the method check on actual requests.

Fixes #4130
@987Nabil
987Nabil force-pushed the fix-4130-cors-non-preflight branch from 87addc1 to 332f601 Compare September 11, 2026 06:58
@987Nabil
987Nabil requested a review from guizmaii September 11, 2026 08:25
@987Nabil
987Nabil merged commit d5ca540 into main Sep 11, 2026
68 of 78 checks passed
@987Nabil
987Nabil deleted the fix-4130-cors-non-preflight branch September 11, 2026 13:24
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.

CORS middleware rejects actual cross-origin requests when method is not in allowedMethods

3 participants