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

CORS: support wildcard matching for AllowMethods and AllowHeaders #4168

Merged
merged 27 commits into from
Sep 17, 2024

Conversation

zhaohuabing
Copy link
Member

@zhaohuabing zhaohuabing commented Sep 6, 2024

Support wildcard matching for AllowMethods and AllowHeaders
Related: #4196

@zhaohuabing zhaohuabing requested a review from a team as a code owner September 6, 2024 08:35
Copy link

codecov bot commented Sep 7, 2024

Codecov Report

Attention: Patch coverage is 76.92308% with 3 lines in your changes missing coverage. Please review.

Project coverage is 66.45%. Comparing base (480b387) to head (fa0ddab).
Report is 15 commits behind head on main.

Files with missing lines Patch % Lines
internal/xds/translator/cors.go 76.92% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4168      +/-   ##
==========================================
- Coverage   66.51%   66.45%   -0.06%     
==========================================
  Files         195      195              
  Lines       23734    23745      +11     
==========================================
- Hits        15786    15780       -6     
- Misses       6831     6841      +10     
- Partials     1117     1124       +7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

zirain
zirain previously approved these changes Sep 9, 2024
guydc
guydc previously approved these changes Sep 9, 2024
Copy link
Contributor

@guydc guydc left a comment

Choose a reason for hiding this comment

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

LGTM. Do we need to label this somehow so that we include a breaking change notice in release notes?

@zhaohuabing zhaohuabing added the release-note Indicates a required release note label Sep 10, 2024
@zhaohuabing
Copy link
Member Author

zhaohuabing commented Sep 10, 2024

Although the Envoy documentation doesn’t explicitly mention it, the implementation currently allows the * symbol to match all HTTP methods and allowheaders.

The current implementation:

allowOrigins: * is used for wildcard matching, and EG translate it to a regex in the generated xDS.
allowMethods: * is treated as a normal character in EG, but Envoy use it to match all methods.
allowHeaders: * is treated as a normal character in EG, but Envoy use it to match all headers.
exposeHeaders * is treated as a normal character in both EG and Envoy. (I have no idea why it's not treated as the same matching logic as the allowHeaders 🤷‍♂️)

While allowing * can be convenient, whitelisting all headers/methods has a better security posture. Should we using wildcard maching for allowHeaders and allowMethods? @envoyproxy/gateway-maintainers @envoyproxy/gateway-reviewers

Test:

cors:
  allowHeaders:
  - '*'
  allowMethods:
  - '*'
  allowOrigins:
  - '*'
  exposeHeaders:
  - '*'
curl -H "Origin: http://www.foo.com/" \
-H "Host: www.example.com" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: Content-Type, x-resp" \
-H "Access-Control-Expose-Headers: xxxxxx, yyyyy" \
-X OPTIONS -v -s \
http://172.18.255.200/  \
1> /dev/null

< HTTP/1.1 200 OK
< access-control-allow-origin: http://www.foo.com/
< access-control-allow-methods: GET
< access-control-allow-headers: Content-Type, x-resp
< access-control-expose-headers: *
< date: Tue, 10 Sep 2024 08:43:47 GMT
< content-length: 0

Slack discussion: https://envoyproxy.slack.com/archives/C03E6NHLESV/p1725956439557039?thread_ts=1725899843.349039&cid=C03E6NHLESV

CORS implementations in some existing gateways, all of them support wildcard in allowOrigins, and some of them support wildcard in headers and methods.

@luvk1412
Copy link
Contributor

luvk1412 commented Sep 10, 2024

Adding my use case here where we require some way to mention Allow all.

  • We want to have a global CORS SecurityPolicy where cluster Operators can restrict the origins only. If Cluster Operator controls the allowHeaders or exposeHeaders, then devs have to come to operators every time they add a new header to their req/resp. Devs can ideally create a separate SecurityPolicy and override, but we would ideally wan't devs to use only predefined ones via label selectors and not allow them to create new SecurityPolicy.
  • For allowMethods, we can add all enums to policy, as enum set is limited, but adding * or some other cleaner approach to allow all would be preferred. I have one more use case in mind but i am not sure if that would be faced practically: Currently allowed enum set contains all the standard Methods but technically methods don't need to be only those, for eg WebDAV protocol(we happen to run a WebDAV server) has methods like PROPFIND etc., but I don't think any browser/js allows hitting non standard methods. So this might not be an issue for CORS, just mentioning in case i am missing something here and someone else can add.

So for us it would be preferable if there is a way to define allow all for allowOrigins , allowMethods, allowHeaders and exposeHeaders
@zhaohuabing

@zhaohuabing

This comment was marked as resolved.

@luvk1412
Copy link
Contributor

From Access-Control-Expose-Headers

For requests without credentials, a server can also respond with a wildcard value

So for requests without creds/cookies, below

  exposeHeaders:
  - '*'

would make it behave like allow all @zhaohuabing

@zhaohuabing zhaohuabing marked this pull request as draft September 11, 2024 00:02
@zhaohuabing zhaohuabing marked this pull request as draft September 11, 2024 00:02
@zhaohuabing zhaohuabing marked this pull request as draft September 11, 2024 00:02
Signed-off-by: Huabing Zhao <[email protected]>
@zhaohuabing zhaohuabing dismissed stale reviews from guydc and zirain via aff831f September 11, 2024 05:09
Signed-off-by: Huabing Zhao <[email protected]>
@zhaohuabing zhaohuabing removed the release-note Indicates a required release note label Sep 11, 2024
@zhaohuabing zhaohuabing changed the title chore: set reasonable validation and field types for CORS CORS: support wildcard matching for AllowMethods and AllowHeaders Sep 11, 2024
Signed-off-by: Huabing Zhao <[email protected]>
@zhaohuabing zhaohuabing marked this pull request as ready for review September 11, 2024 15:33
Signed-off-by: Huabing Zhao <[email protected]>
Signed-off-by: Huabing Zhao <[email protected]>
Signed-off-by: Huabing Zhao <[email protected]>
Signed-off-by: Huabing Zhao <[email protected]>
Signed-off-by: Huabing Zhao <[email protected]>
Signed-off-by: Huabing Zhao <[email protected]>
Signed-off-by: Huabing Zhao <[email protected]>
Signed-off-by: Huabing Zhao <[email protected]>
Signed-off-by: Huabing Zhao <[email protected]>
Signed-off-by: Huabing Zhao <[email protected]>
@zhaohuabing
Copy link
Member Author

zhaohuabing commented Sep 12, 2024

From Access-Control-Expose-Headers

For requests without credentials, a server can also respond with a wildcard value

So for requests without creds/cookies, below

  exposeHeaders:
  - '*'

would make it behave like allow all @zhaohuabing

I misunderstood the access-control-expose-headers header. It's enforced by the browser when the browser receive responses. So just allowing inputting * in the exposeHeaders is good enough. :-)

@zhaohuabing zhaohuabing requested a review from arkodg September 12, 2024 16:21
Copy link
Contributor

@arkodg arkodg left a comment

Choose a reason for hiding this comment

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

LGTM thanks !

@arkodg arkodg requested review from a team September 16, 2024 18:33
@zirain zirain merged commit ab122db into envoyproxy:main Sep 17, 2024
27 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.

5 participants