Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[💡 FEATURE REQUEST]: HTTP Middleware - Dynamic CORS origin support #1709

Closed
orlandothoeny opened this issue Sep 8, 2023 · 5 comments · Fixed by roadrunner-server/headers#64
Assignees
Labels
C-feature-request Category: feature requested, but need to be discussed
Milestone

Comments

@orlandothoeny
Copy link

orlandothoeny commented Sep 8, 2023

Plugin

HTTP Middleware (any)

I have an idea!

Affected middleware: HTTP

The only thing that prevents us from completely getting rid of our NGINX is CORS support for wildcard subdomains.
The HTTP middleware currently only supports returning static values for the CORS headers.

Use case

We have a PHP API, this API is used by multiple sites that run on the same main domain.

Example

The API is running under api.example.com. We have example.com, cockpit.example.com, admin.example.com and various other sites that all call api.example.com via JavaScript in the browser. Thus, all these hostnames must be allowed as CORS origin.

This also applies to our staging & development environment, which run on the same main domain but under a separate subdomain. E.g. api.dev.example.com, dev.example.com, cockpit.dev.example.com & admin.dev.example.com.

Due to the large volume of hosts and differences between the environments, we decided to use a Regex pattern that allows the main domain, as well as all subdomains below it. This saves us the complexity of having to maintain a separate list of allowed hosts for every environment.

To accomplish this, we use the following NGINX config:

# Allow example.com and all example.com subdomains and sub-subdomains
map $http_origin $allow_origin {
    ~^https://(.*\.)+example.com(:\d+)?$ $http_origin;
    https://example.com https://example.com;
    default "";
}

more_set_headers "Access-Control-Allow-Origin: $allow_origin";

Feature request

HTTP Middleware support that allows us to return the requesting host as allowed_origin value if it is one of these:

  • example.com
  • Subdomain of example.com
  • Sub-subdomain of example.com.
  • etc..

Possible implementation ideas

  • Regex support. Similar to the NGINX config above. Probably the most flexible?
  • Wildcard config. Something like allowed_origin_wildcard: '*.example.com'
  • Definition of the main domain, allowing it and all hosts below it: allowed_origin_root: 'example.com'
  • ...

Config ideas

Either create a new separate key for the matching-config. Or a new matching-type config.
For example:

  1. allowed_origin || allowed_origin_wildcard
    • Probably more complicated because there would have to be a order of precedence?
  2. allowed_origin && allowed_origin_type=['simple' || 'regex']
@orlandothoeny orlandothoeny added the C-feature-request Category: feature requested, but need to be discussed label Sep 8, 2023
@rustatian
Copy link
Member

Hey @orlandothoeny 👋🏻
Oh, this is super detailed feature request, good job 👍🏻 ❤️
The currently available allowed_origin option supports basic wildcards, such as: *.example.com. Is this something that can help you? Until I implement a more advanced version with regexp.

@orlandothoeny
Copy link
Author

Hi @rustatian,

Thanks for the quick reply :)

I just saw that the middleware uses https://github.com/rs/cors, I'll have to try that out. In the test-cases I only found one with a simple subdomain, no nested ones: https://github.com/rs/cors/blob/20a76bd635d3c8a7ea58f49fad54b8eecb95aa46/cors_test.go#L116 Maybe it just works. Then nothing would have to change to be able to accomplish this. Except maybe to add this to the docs to prevent future issues.

@orlandothoeny
Copy link
Author

orlandothoeny commented Sep 8, 2023

I don't know Go, but just by looking at the code I think that should work. I don't see any special subdomain logic. I think it's just a simple wildcard with a prefix + suffix check. So something like allowed_origin: https://*.example.com should work

@orlandothoeny
Copy link
Author

Just realized that that wouldn't allow https://example.com. And using allowed_origin: https://*example.com would also permit requests from https://i-am-an-evil-hackerman-example.com

@rustatian
Copy link
Member

Oh yeah, you're right. Looks like regex pattern matching would be best here. Since I'm able to provide my implementation for the allow logic, it would be possible to use regexp here.
I'll put this FR to the next release, v2023.4 (or v2024). It would be available much sooner as a beta release.

@rustatian rustatian added this to the v2024 milestone Sep 8, 2023
@rustatian rustatian moved this to 🆕 New in Jira 😄 Sep 8, 2023
@rustatian rustatian moved this from 🆕 New to 🏗 In progress in Jira 😄 Nov 4, 2023
@rustatian rustatian modified the milestones: v2024.1.0, v2023.3.4 Nov 4, 2023
@github-project-automation github-project-automation bot moved this from 🏗 In progress to ✅ Done in Jira 😄 Nov 4, 2023
@rustatian rustatian mentioned this issue Nov 9, 2023
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: feature requested, but need to be discussed
Projects
Status: ✅ Done
Development

Successfully merging a pull request may close this issue.

2 participants