-
Notifications
You must be signed in to change notification settings - Fork 152
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
fix: add CORS to config, improve test #654
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #654 +/- ##
==========================================
- Coverage 51.96% 51.82% -0.14%
==========================================
Files 157 159 +2
Lines 13454 13567 +113
==========================================
+ Hits 6991 7031 +40
- Misses 5891 5967 +76
+ Partials 572 569 -3 ☔ View full report in Codecov by Sentry. |
allowed_origins: | ||
- "" # do not allow any origins |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need an empty string, an empty list should have the same meaning, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in gorilla by default an empty list equals to "*"
https://github.com/gorilla/handlers/blob/9c61bd81e701cf500437e1b516b675cdd3b73ca7/cors.go#L117
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should always prepend the public http origin to the list so that it has at least one item
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK before this PR even the public url was not an allowed origin. So I set "" and do not allow any origins to match the original behaviour
Do you think we should make the default less safe but more convenient? If so, I can prepend c.HTTP.PublicURL
to c.HTTP.CORS.AllowedOrigins
in the Config.Validate()
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, the Soft Serve public URL would usually be the origin where we expect requests to come from. IMO, it should always be included in the list of allowed origins or be defined in an allowed origins validator.
CORS: CORSConfig{ | ||
AllowedHeaders: []string{"Accept", "Accept-Language", "Content-Language", "Origin"}, | ||
AllowedMethods: []string{"GET", "HEAD", "POST"}, | ||
AllowedOrigins: []string{""}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't an empty slice have the same meaning?
AllowedOrigins: []string{""}, | |
AllowedOrigins: []string{}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An empty slice fallsback to "*" in gorilla
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the behavior of using Soft Serve without a CORS middleware?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
afaik before #516 added cors middleware all cors/browser requests failed because soft-serve never returned any cors headers
allowed_origins: | ||
- "" # do not allow any origins |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need an empty string, an empty list should have the same meaning, no?
# The allowed cross-origin URLs | ||
allowed_origins: | ||
- "" # do not allow any origins |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- "" # do not allow any origins | |
# - * # Allow all origins don't do this unless you know what you're doing ;) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with gorilla docs that returning * is unsafe and not required in any case
https://github.com/gorilla/handlers/blob/9c61bd81e701cf500437e1b516b675cdd3b73ca7/cors.go#L122
So I do not suggest "*" to avoid giving users poor advice.
Do you think it is better to offer a specific example here, like "https://website.com"?
curl -v --request OPTIONS http://localhost:$HTTP_PORT/repo2.git/info/refs -H 'Origin: https://foo.example' -H 'Access-Control-Request-Method: GET' | ||
stderr '.*Method Not Allowed.*' | ||
curl -v --request OPTIONS http://localhost:$HTTP_PORT/repo2/git-upload-pack -H 'Origin: https://foo.example' -H 'Access-Control-Request-Method: POST' | ||
! stderr '.*Access-Control-Allow-Origin.*' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This case should fail because the origin is not the same i.e. not localhost
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this case is correct
localhost
is not the origin, localhost
is the endpoint of the server to which we send a request with an "Origin: https://foo.example" header.
Origin is the value of the Origin
header. usually origin is the value of browser's URL bar. Here origin is https://foo.example
.
In the first test case, the server by default does not allow any origins, so the response does not have the "Access-Control-Allow-Origin" header.
In the second case the server allows the origin, and replies to OPTIONS with an "Access-Control-Allow-Origin" header. Usually after this the browser checks that the server response contains "Access-Control-Allow-Origin" and proceeds with the POST response.
What can make this test more readable and intuitive in your opinion?
- GET | ||
- HEAD | ||
- POST | ||
# - PUT | ||
# - OPTIONS | ||
- GET | ||
- HEAD | ||
- POST |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also need to allow PUT because LFS uses them. Don't we also need OPTIONS too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made sure that default behaviour stays the same, by default without cors middleware gorilla only allowed get, head and post. https://github.com/gorilla/handlers/blob/9c61bd81e701cf500437e1b516b675cdd3b73ca7/cors.go#L30
Options is always allowed in gorilla, as an exception. https://github.com/gorilla/handlers/blob/9c61bd81e701cf500437e1b516b675cdd3b73ca7/handlers.go#L19
OK, I'll enable PUT and OPTIONS in default config
Hotfix for #516, I've corrected the test case and added CORS to the default config.