mirror of
https://github.com/argoproj/argo-cd
synced 2026-04-21 08:57:17 +00:00
fix: Add X-Frame-Options and CSP headers to Swagger UI endpoints (#26521)
Signed-off-by: rohansood10 <rohansood10@users.noreply.github.com> Signed-off-by: Blake Pettersson <blake.pettersson@gmail.com> Co-authored-by: rohansood10 <rohansood10@users.noreply.github.com> Co-authored-by: Blake Pettersson <blake.pettersson@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
e21d471965
commit
68cbd05e52
2 changed files with 28 additions and 4 deletions
|
|
@ -11,20 +11,29 @@ import (
|
|||
// filename of ReDoc script in UI's assets/scripts path
|
||||
const redocScriptName = "redoc.standalone.js"
|
||||
|
||||
// withFrameOptions wraps an http.Handler to set headers that prevent iframe embedding (clickjacking protection).
|
||||
func withFrameOptions(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("X-Frame-Options", "DENY")
|
||||
w.Header().Set("Content-Security-Policy", "frame-ancestors 'none'")
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// ServeSwaggerUI serves the Swagger UI and JSON spec.
|
||||
func ServeSwaggerUI(mux *http.ServeMux, swaggerJSON string, uiPath string, rootPath string) {
|
||||
prefix := path.Dir(uiPath)
|
||||
swaggerPath := path.Join(prefix, "swagger.json")
|
||||
mux.HandleFunc(swaggerPath, func(w http.ResponseWriter, _ *http.Request) {
|
||||
mux.Handle(swaggerPath, withFrameOptions(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
_, _ = fmt.Fprint(w, swaggerJSON)
|
||||
})
|
||||
})))
|
||||
|
||||
specURL := path.Join(prefix, rootPath, "swagger.json")
|
||||
scriptURL := path.Join(prefix, rootPath, "assets", "scripts", redocScriptName)
|
||||
mux.Handle(uiPath, middleware.Redoc(middleware.RedocOpts{
|
||||
mux.Handle(uiPath, withFrameOptions(middleware.Redoc(middleware.RedocOpts{
|
||||
BasePath: prefix,
|
||||
SpecURL: specURL,
|
||||
Path: path.Base(uiPath),
|
||||
RedocURL: scriptURL,
|
||||
}, http.NotFoundHandler()))
|
||||
}, http.NotFoundHandler())))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,4 +52,19 @@ func TestSwaggerUI(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Equalf(t, http.StatusOK, resp.StatusCode, "Was expecting status code 200 from swagger-ui, but got %d instead", resp.StatusCode)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
|
||||
// Verify clickjacking protection headers on swagger.json
|
||||
require.Equal(t, "DENY", resp.Header.Get("X-Frame-Options"))
|
||||
require.Equal(t, "frame-ancestors 'none'", resp.Header.Get("Content-Security-Policy"))
|
||||
|
||||
// Verify clickjacking protection headers on swagger-ui
|
||||
uiReq, err := http.NewRequestWithContext(t.Context(), http.MethodGet, server+"/swagger-ui", http.NoBody)
|
||||
require.NoError(t, err)
|
||||
|
||||
uiResp, err := http.DefaultClient.Do(uiReq)
|
||||
require.NoError(t, err)
|
||||
require.Equalf(t, http.StatusOK, uiResp.StatusCode, "Was expecting status code 200 from swagger-ui, but got %d instead", uiResp.StatusCode)
|
||||
require.Equal(t, "DENY", uiResp.Header.Get("X-Frame-Options"))
|
||||
require.Equal(t, "frame-ancestors 'none'", uiResp.Header.Get("Content-Security-Policy"))
|
||||
require.NoError(t, uiResp.Body.Close())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue