Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: strip CORS headers from applications #8057

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

Merged
merged 1 commit into from
Jun 21, 2023
Merged

Conversation

code-asher
Copy link
Member

@code-asher code-asher commented Jun 15, 2023

This is a followup to #7688

The problem is that if applications send their own CORS headers the headers get doubled up (not overwritten) and browsers do not like multiple values for the allowed origin even though it appears the spec allows for it.

We could prefer the application's headers instead of ours but since we control OPTIONS I think preferring ours will by the more consistent experience across the board and also aligns with the original RFC.

Closes #8010.

@code-asher code-asher changed the title Strip CORS headers from applications fix: strip CORS headers from applications Jun 15, 2023
@code-asher code-asher force-pushed the asher/override-cors branch 16 times, most recently from e84d992 to 9aa2e85 Compare June 16, 2023 00:54
Comment on lines +1301 to +1316
// Somehow there are two "Origin"s in Vary even though there should only be
// one (from the CORS middleware), even if you remove the headers being sent
// above. When I do nothing else but change the expected value below to
// have two "Origin"s suddenly Vary only has one. It is somehow always the
// opposite of whatever I put for the expected. So, reluctantly, remove
// duplicate "Origin" values.
var deduped []string
var addedOrigin bool
for _, value := range resp.Header.Values("Vary") {
if value != "Origin" || !addedOrigin {
if value == "Origin" {
addedOrigin = true
}
deduped = append(deduped, value)
}
}
Copy link
Member Author

@code-asher code-asher Jun 16, 2023

Choose a reason for hiding this comment

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

I must be going mad, I have no idea how the response headers could change in perfect opposition to what I pass into the require.Equal for the expected value.

Examples of it swapping:
https://github.com/coder/coder/actions/runs/5284785388/jobs/9562577501
https://github.com/coder/coder/actions/runs/5284691553/jobs/9562383538

And all I did was add "Origin", to the check.

It happens consistently despite multiple attempts, always exactly the opposite. Could be a flake and just a coincidence that it always lines up with me changing the expected value...

Copy link
Member

Choose a reason for hiding this comment

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

Headers should be case insensitive anyway. Vary: origin,Origin should be equal to Vary: origin. So this is fine imo.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oddly it was two Origin strings, same capitalization. It seems so bizarre that the headers returned could change based on how I change completely unrelated code, so bizarre that I feel I must be doing something dunderheaded.

@code-asher code-asher marked this pull request as ready for review June 16, 2023 01:21
@code-asher code-asher requested a review from Emyrk June 16, 2023 01:21
Copy link
Member

@bpmct bpmct left a comment

Choose a reason for hiding this comment

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

Do we need to change this section in our docs?

Applications can set their own headers which will override the defaults but this will only apply to non-preflight requests. Preflight requests through the dashboard are never sent to applications and thus cannot be modified by them. Read more about the difference between simple requests and requests that trigger preflights here.

@code-asher
Copy link
Member Author

Do we need to change this section in our docs?

Applications can set their own headers which will override the defaults but this will only apply to non-preflight requests. Preflight requests through the dashboard are never sent to applications and thus cannot be modified by them. Read more about the difference between simple requests and requests that trigger preflights here.

Yup, this PR also makes changes to this section. Let me know if you have any thoughts on the wording! https://github.com/coder/coder/pull/8057/files#diff-fee7817d909d710ad6c6a59e4a5fc65ea0b7608949e74c45e3465b1f51e5cc99R127-R132

The problem is that the headers get doubled up (not overwritten) and
browsers do not like multiple values for the allowed origin even though
it appears the spec allows for it.

We could prefer the application's headers instead of ours but since we
control OPTIONS I think preferring ours will by the more consistent
experience and also aligns with the original RFC.
@code-asher code-asher force-pushed the asher/override-cors branch from 9aa2e85 to 4fabc54 Compare June 20, 2023 15:54
Copy link
Member

@Emyrk Emyrk left a comment

Choose a reason for hiding this comment

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

LGTM 👍

Comment on lines +550 to +561
varies := r.Header.Values(httpmw.VaryHeader)
r.Header.Del(httpmw.VaryHeader)
forbiddenVary := []string{
httpmw.OriginHeader,
httpmw.AccessControlRequestMethodsHeader,
httpmw.AccessControlRequestHeadersHeader,
}
for _, value := range varies {
if !slice.ContainsCompare(forbiddenVary, value, strings.EqualFold) {
r.Header.Add(httpmw.VaryHeader, value)
}
}
Copy link
Member

Choose a reason for hiding this comment

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

What is this part doing?

Copy link
Member Author

@code-asher code-asher Jun 20, 2023

Choose a reason for hiding this comment

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

I figure an application might Vary based on headers other than CORS-related headers, so I am adding back the ones that are not related to CORS. So if you have Vary: Access-Control-Request-Methods and Vary: X-Foobar the former gets removed while the latter gets kept.

Edit: I said the wrong thing initially, the latter gets kept not axed.

Comment on lines +1301 to +1316
// Somehow there are two "Origin"s in Vary even though there should only be
// one (from the CORS middleware), even if you remove the headers being sent
// above. When I do nothing else but change the expected value below to
// have two "Origin"s suddenly Vary only has one. It is somehow always the
// opposite of whatever I put for the expected. So, reluctantly, remove
// duplicate "Origin" values.
var deduped []string
var addedOrigin bool
for _, value := range resp.Header.Values("Vary") {
if value != "Origin" || !addedOrigin {
if value == "Origin" {
addedOrigin = true
}
deduped = append(deduped, value)
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Headers should be case insensitive anyway. Vary: origin,Origin should be equal to Vary: origin. So this is fine imo.

@bpmct
Copy link
Member

bpmct commented Jun 21, 2023

Do we need to change this section in our docs?

Applications can set their own headers which will override the defaults but this will only apply to non-preflight requests. Preflight requests through the dashboard are never sent to applications and thus cannot be modified by them. Read more about the difference between simple requests and requests that trigger preflights here.

Yup, this PR also makes changes to this section. Let me know if you have any thoughts on the wording! https://github.com/coder/coder/pull/8057/files#diff-fee7817d909d710ad6c6a59e4a5fc65ea0b7608949e74c45e3465b1f51e5cc99R127-R132

Somehow I totally missed the docs changes when I initially reviewed. All LGTM.

@code-asher code-asher merged commit 96f9e61 into main Jun 21, 2023
@code-asher code-asher deleted the asher/override-cors branch June 21, 2023 21:41
@github-actions github-actions bot locked and limited conversation to collaborators Jun 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handle case where application sends conflicting CORS headers
3 participants