mirror of
https://github.com/project-zot/zot.git
synced 2026-06-15 11:37:56 +08:00
security: suppress Allow-Credentials on wildcard CORS origin (CORS-1) (#3980)
fix(security): suppress Allow-Credentials on wildcard CORS origin (CORS-1) Per CORS spec §3.2, Access-Control-Allow-Credentials must not be "true" when Access-Control-Allow-Origin is the wildcard "*". ACHeadersMiddleware (pkg/common/http_server.go) and getUIHeadersHandler (pkg/api/routes.go) now only emit the credentials header when an explicit, non-empty AllowOrigin is configured. Deployments that leave AllowOrigin blank (default wildcard) no longer produce a contradictory header pair. Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
This commit is contained in:
committed by
GitHub
parent
eadc9b65ed
commit
bfc59ad120
+7
-3
@@ -248,9 +248,12 @@ func getUIHeadersHandler(config *config.Config, allowedMethods ...string) func(h
|
||||
response.Header().Set("Access-Control-Allow-Headers",
|
||||
"Authorization,content-type,"+constants.SessionClientHeaderName)
|
||||
|
||||
// Get auth config safely
|
||||
// Access-Control-Allow-Credentials must not be "true" when
|
||||
// Access-Control-Allow-Origin is the wildcard "*" (CORS spec §3.2).
|
||||
// Only advertise credentials support when an explicit origin is set.
|
||||
authConfig := config.CopyAuthConfig()
|
||||
if authConfig.IsBasicAuthnEnabled() {
|
||||
allowOrigin := strings.TrimSpace(config.GetAllowOrigin())
|
||||
if authConfig.IsBasicAuthnEnabled() && allowOrigin != "" && allowOrigin != "*" {
|
||||
response.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
}
|
||||
|
||||
@@ -517,7 +520,8 @@ type ExtensionList struct {
|
||||
func (rh *RouteHandler) GetManifest(response http.ResponseWriter, request *http.Request) {
|
||||
// Get auth config safely
|
||||
authConfig := rh.c.Config.CopyAuthConfig()
|
||||
if authConfig.IsBasicAuthnEnabled() {
|
||||
allowOrigin := strings.TrimSpace(rh.c.Config.GetAllowOrigin())
|
||||
if authConfig.IsBasicAuthnEnabled() && allowOrigin != "" && allowOrigin != "*" {
|
||||
response.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
}
|
||||
|
||||
|
||||
@@ -241,6 +241,38 @@ func TestRoutes(t *testing.T) {
|
||||
|
||||
defer resp.Body.Close()
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.Header.Get("Access-Control-Allow-Credentials"), ShouldEqual, "")
|
||||
So(resp.StatusCode, ShouldEqual, http.StatusNotFound)
|
||||
})
|
||||
|
||||
Convey("Get manifest with explicit AllowOrigin emits credentials header", func() {
|
||||
ctlr.StoreController.DefaultStore = &mocks.MockedImageStore{
|
||||
GetImageManifestFn: func(repo string, reference string) ([]byte, godigest.Digest, string, error) {
|
||||
return []byte{}, "", "", zerr.ErrRepoBadVersion
|
||||
},
|
||||
}
|
||||
|
||||
originalAllowOrigin := ctlr.Config.HTTP.AllowOrigin
|
||||
ctlr.Config.HTTP.AllowOrigin = "https://example.com"
|
||||
|
||||
defer func() {
|
||||
ctlr.Config.HTTP.AllowOrigin = originalAllowOrigin
|
||||
}()
|
||||
|
||||
request, _ := http.NewRequestWithContext(context.TODO(), http.MethodGet, baseURL, nil)
|
||||
request = mux.SetURLVars(request, map[string]string{
|
||||
"name": "test",
|
||||
"reference": "b8b1231908844a55c251211c7a67ae3c809fb86a081a8eeb4a715e6d7d65625c",
|
||||
})
|
||||
response := httptest.NewRecorder()
|
||||
|
||||
rthdlr.GetManifest(response, request)
|
||||
|
||||
resp := response.Result()
|
||||
|
||||
defer resp.Body.Close()
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.Header.Get("Access-Control-Allow-Credentials"), ShouldEqual, "true")
|
||||
So(resp.StatusCode, ShouldEqual, http.StatusNotFound)
|
||||
})
|
||||
|
||||
|
||||
@@ -38,9 +38,12 @@ func ACHeadersMiddleware(config *config.Config, allowedMethods ...string) mux.Mi
|
||||
resp.Header().Set("Access-Control-Allow-Methods", allowedMethodsValue)
|
||||
resp.Header().Set("Access-Control-Allow-Headers", "Authorization,content-type,"+constants.SessionClientHeaderName)
|
||||
|
||||
// Get auth config safely
|
||||
// Access-Control-Allow-Credentials must not be "true" when
|
||||
// Access-Control-Allow-Origin is the wildcard "*" (CORS spec §3.2).
|
||||
// Only advertise credentials support when an explicit origin is set.
|
||||
authConfig := config.CopyAuthConfig()
|
||||
if authConfig.IsBasicAuthnEnabled() {
|
||||
allowOrigin := strings.TrimSpace(config.GetAllowOrigin())
|
||||
if authConfig.IsBasicAuthnEnabled() && allowOrigin != "" && allowOrigin != "*" {
|
||||
resp.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user