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

GEP 1767: CORS Filter #3435

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open

Conversation

lianglli
Copy link

@lianglli lianglli commented Nov 5, 2024

What type of PR is this?
/kind gep

What this PR does / why we need it:
This GEP proposes to add a new field HTTPCORSFilter to HTTPRouteFilter.

Which issue(s) this PR fixes:
Fixes #1767

Does this PR introduce a user-facing change?:

NONE

@k8s-ci-robot
Copy link
Contributor

Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added kind/gep PRs related to Gateway Enhancement Proposal(GEP) do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Nov 5, 2024
@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Nov 5, 2024
@k8s-ci-robot
Copy link
Contributor

Hi @lianglli. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Nov 5, 2024
@youngnick
Copy link
Contributor

Thanks for the energy here @liangli, but the correct process here is for you to add some discussion about this feature to the proposed set of Experimental changes in #3403, and then, if this CORS GEP is selected for an Experimental slot by the community's voting, this PR will be able to move forward.

This is a useful feature that already has a GEP, has been discussed before, and is not too big, so it's reasonably likely that it will be included if we can free up enough Experimental slots by moving things to Standard.

I note that you added this to the 1.2 Experimental discussion as well, so it's fine to just reuse the same description in the v1.3 scoping discussion there so that any new folks will have the context to vote.

Until then, sadly, this PR will need to be on hold.

/hold

@robscott
Copy link
Member

robscott commented Dec 6, 2024

Thanks for writing up this GEP @lianglli! This made the cut for v1.3 release scoping, it's great to already have a GEP PR ready for review, will take a look shortly.

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Dec 6, 2024
Copy link
Member

@robscott robscott left a comment

Choose a reason for hiding this comment

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

Thanks for all your work on this @lianglli! This is incredibly detailed and well written. I took a first pass and left some initial comments.

/cc @strongjz @howardjohn @youngnick

Comment on lines 187 to 189
// When responding to a credentialed requests, the gateway must specify
// one or more HTTP headers in the value of the Access-Control-Allow-Headers response header,
// instead of specifying the * wildcard.
Copy link
Member

Choose a reason for hiding this comment

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

What happens if a user has configured * here? Should the Gateway implementation reject the request? Or do we just need to add CEL validation to prevent allowCredentials being set to true at the same time as this is set to *?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think you may be mixing up the user HTTPRoute config and the server's expected response. a user can legitimately set * in the config certainly -- this seems to be saying they cannot set it in the response header.

However, I am not sure why? The spec does not seem to reject *? https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers#syntax

Copy link

Choose a reason for hiding this comment

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

We had someone in ingress-nginx, request that we updated CORS to accept * and null

kubernetes/ingress-nginx#12402

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

What happens if a user has configured * here? Should the Gateway implementation reject the request? Or do we just need to add CEL validation to prevent allowCredentials being set to true at the same time as this is set to *?

When responding to a credentialed requests, the response headers Access-Control-Allow-Origin, Access-Control-Expose-Headers, Access-Control-Allow-Methods and Access-Control-Allow-Headers can NOT use * as value.

However, if a HTTPCORSFilter sets AllowCredentials as true and configures * for AllowHeaders, the gateway will return HTTP response header Access-Control-Allow-Credentials: true and Access-Control-Allow-Headers: * to the "preflight" request based on the HTTPCORSFilter specifically.

Then, clients will NOT be able to send actual cross-origin request.

Copy link
Author

@lianglli lianglli Dec 10, 2024

Choose a reason for hiding this comment

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

Note that Envoy can't return * directly because it treats * specially: https://github.com/envoyproxy/envoy/blob/6445d0dcdd33413e47454221fa80b3cfabea7d4e/source/extensions/filters/http/cors/cors_filter.cc#L159-L163.

Most gateways support the * wildcard as the value of a HTTP header.
Moreover, * wildcard is a valid character of header value based on rfc7230.

Hence, the envoy should support it in future.

Copy link
Contributor

Choose a reason for hiding this comment

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

This field (and this spec in general) is pretty unclear as to which "user" we're talking about.

I suggest using different names for the HTTPRoute owner (maybe "user" is okay here), and the client, (should probably use that word instead).

So, I think what @robscott was saying is "What happens if the HTTPRoute owner has configured * here?"

The text says:

    // When responding to a credentialed requests, the gateway must specify 
    // one or more HTTP headers in the value of the Access-Control-Allow-Headers response header, 
    // instead of specifying the * wildcard.

What headers should the implementation respond with? Below, @spacewander suggests responding with whatever was sent in the Access-Control-Request-Headers field in the OPTIONS request. Whatever we want to do MUST be defined in this field, as what to do in the other cases:

  • * is configured in this field, and Access-Control-Request-Headers is not sent
  • One or more values are configured in this field and Access-Control-Request-Headers is sent
  • One or more values are configured in this field and Access-Control-Request-Headers is not sent

What we are aiming for is that someone who reads the spec should be able to understand enough to write conformance tests for the spec, ideally without looking at any other documents.

geps/gep-1767/index.md Show resolved Hide resolved
geps/gep-1767/index.md Show resolved Hide resolved
@robscott robscott added this to the v1.3.0 milestone Dec 7, 2024
Copy link
Contributor

@howardjohn howardjohn left a comment

Choose a reason for hiding this comment

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

Thanks for the GEP -- top notch details!

geps/gep-1767/index.md Outdated Show resolved Hide resolved
geps/gep-1767/index.md Show resolved Hide resolved
geps/gep-1767/index.md Outdated Show resolved Hide resolved
Comment on lines 187 to 189
// When responding to a credentialed requests, the gateway must specify
// one or more HTTP headers in the value of the Access-Control-Allow-Headers response header,
// instead of specifying the * wildcard.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you may be mixing up the user HTTPRoute config and the server's expected response. a user can legitimately set * in the config certainly -- this seems to be saying they cannot set it in the response header.

However, I am not sure why? The spec does not seem to reject *? https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers#syntax

geps/gep-1767/index.md Show resolved Hide resolved
geps/gep-1767/index.md Show resolved Hide resolved
geps/gep-1767/index.md Outdated Show resolved Hide resolved
geps/gep-1767/index.md Outdated Show resolved Hide resolved
Comment on lines 187 to 189
// When responding to a credentialed requests, the gateway must specify
// one or more HTTP headers in the value of the Access-Control-Allow-Headers response header,
// instead of specifying the * wildcard.
Copy link
Contributor

Choose a reason for hiding this comment

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

geps/gep-1767/index.md Outdated Show resolved Hide resolved
geps/gep-1767/index.md Outdated Show resolved Hide resolved
geps/gep-1767/index.md Outdated Show resolved Hide resolved
geps/gep-1767/index.md Show resolved Hide resolved
geps/gep-1767/index.md Outdated Show resolved Hide resolved
geps/gep-1767/index.md Show resolved Hide resolved
geps/gep-1767/metadata.yaml Outdated Show resolved Hide resolved
geps/gep-1767/index.md Outdated Show resolved Hide resolved
geps/gep-1767/index.md Outdated Show resolved Hide resolved
geps/gep-1767/index.md Outdated Show resolved Hide resolved
Comment on lines 203 to 215
// ExposeHeaders indicates which HTTP response headers are exposed to clients
// for the cross-origin request that is not a "preflight" request.
// Header names are not case sensitive.
//
// Config:
// exposeHeaders: ["Content-Security-Policy"]
// Output:
// Access-Control-Expose-Headers: Content-Security-Policy
//
// A wildcard indicates that the responses with all HTTP headers are exposed to clients.
// When responding to a credentialed requests, the gateway must specify
// one or more HTTP headers in the value of the Access-Control-Expose-Headers response header,
// instead of specifying the * wildcard.
Copy link
Contributor

Choose a reason for hiding this comment

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

Does "exposed to clients" mean "returned as headers in requests"? Seems like it, but if that's the case, that should be said specifically here. Once we define that, then we can use "exposed to clients" and "returned as headers" interchangeably.

geps/gep-1767/index.md Outdated Show resolved Hide resolved
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lianglli
Once this PR has been reviewed and has the lgtm label, please assign mlavacca for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. kind/gep PRs related to Gateway Enhancement Proposal(GEP) ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

GEP: Add support for CORS
9 participants