From dd40d05d6ce38923cb8731074c791604ac70f0b2 Mon Sep 17 00:00:00 2001 From: Alex Collins Date: Thu, 7 May 2020 09:10:19 -0700 Subject: [PATCH 1/2] feat(ui) Enable CSP, HSTS, X-Frame-Options. Fixes #2760, #1376, #2761 --- server/apiserver/argoserver.go | 2 +- server/static/static.go | 11 +++++++++-- ui/src/app/assets/fonts/Heebo-Regular.ttf | Bin 0 -> 59404 bytes ui/src/app/assets/styles/heebo.css | 18 ++++++++++++++++++ ui/src/app/index.html | 2 +- ui/src/app/webpack.config.js | 2 ++ 6 files changed, 31 insertions(+), 4 deletions(-) create mode 100755 ui/src/app/assets/fonts/Heebo-Regular.ttf create mode 100644 ui/src/app/assets/styles/heebo.css diff --git a/server/apiserver/argoserver.go b/server/apiserver/argoserver.go index 22740ddd4100..9a1a22851a2a 100644 --- a/server/apiserver/argoserver.go +++ b/server/apiserver/argoserver.go @@ -257,7 +257,7 @@ func (as *argoServer) newHTTPServer(ctx context.Context, port int, artifactServe mux.Handle("/api/", gwmux) mux.HandleFunc("/artifacts/", artifactServer.GetArtifact) mux.HandleFunc("/artifacts-by-uid/", artifactServer.GetArtifactByUID) - mux.HandleFunc("/", static.NewFilesServer(as.baseHRef).ServerFiles) + mux.HandleFunc("/", static.NewFilesServer(as.baseHRef, as.tlsConfig != nil).ServerFiles) return &httpServer } diff --git a/server/static/static.go b/server/static/static.go index feac4a68344c..76f3d530f947 100644 --- a/server/static/static.go +++ b/server/static/static.go @@ -8,10 +8,11 @@ import ( type FilesServer struct { baseHRef string + secure bool } -func NewFilesServer(baseHRef string) *FilesServer { - return &FilesServer{baseHRef} +func NewFilesServer(baseHRef string, secure bool) *FilesServer { + return &FilesServer{baseHRef, secure} } func (s *FilesServer) ServerFiles(w http.ResponseWriter, r *http.Request) { @@ -26,6 +27,12 @@ func (s *FilesServer) ServerFiles(w http.ResponseWriter, r *http.Request) { w = &responseRewriter{ResponseWriter: w, old: []byte(``), new: []byte(fmt.Sprintf(``, s.baseHRef))} } + w.Header().Set("X-Frame-Options", "DENY") + w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-inline'") + if s.secure { + w.Header().Set("Strict-Transport-Security", "max-age=31536000") + } + // in my IDE (IntelliJ) the next line is red for some reason - but this is fine ServeHTTP(w, r) } diff --git a/ui/src/app/assets/fonts/Heebo-Regular.ttf b/ui/src/app/assets/fonts/Heebo-Regular.ttf new file mode 100755 index 0000000000000000000000000000000000000000..d693084198359f0a7a74f5a41c11e9bbb232b9f2 GIT binary patch literal 59404 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 Argo - + diff --git a/ui/src/app/webpack.config.js b/ui/src/app/webpack.config.js index 77549118b3df..8432fe50958f 100644 --- a/ui/src/app/webpack.config.js +++ b/ui/src/app/webpack.config.js @@ -54,6 +54,8 @@ const config = { from: 'node_modules/argo-ui/src/assets', to: 'assets' }, { from: 'node_modules/@fortawesome/fontawesome-free/webfonts', to: 'assets/fonts' + }, { + from: 'src/app/assets', to: 'assets' }]), ], devServer: { From c2470fa54d0b695cc0db2d50cb4d21b2e24d5ace Mon Sep 17 00:00:00 2001 From: Alex Collins Date: Fri, 8 May 2020 13:02:45 -0700 Subject: [PATCH 2/2] feat-csp --- cmd/argo/commands/server.go | 3 +++ server/apiserver/argoserver.go | 6 +++++- server/static/static.go | 8 ++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cmd/argo/commands/server.go b/cmd/argo/commands/server.go index 011bf1abd4d8..1d4d64f1028f 100644 --- a/cmd/argo/commands/server.go +++ b/cmd/argo/commands/server.go @@ -28,6 +28,7 @@ func NewServerCommand() *cobra.Command { port int baseHRef string secure bool + htst bool namespaced bool // --namespaced managedNamespace string // --managed-namespace enableOpenBrowser bool @@ -86,6 +87,7 @@ See %s`, help.ArgoSever), opts := apiserver.ArgoServerOpts{ BaseHRef: baseHRef, TLSConfig: tlsConfig, + HSTS: htst, Namespace: namespace, WfClientSet: wflientset, KubeClientset: kubeConfig, @@ -121,6 +123,7 @@ See %s`, help.ArgoSever), command.Flags().StringVar(&baseHRef, "basehref", defaultBaseHRef, "Value for base href in index.html. Used if the server is running behind reverse proxy under subpath different from /. Defaults to the environment variable BASE_HREF.") // "-e" for encrypt, like zip command.Flags().BoolVarP(&secure, "secure", "e", false, "Whether or not we should listen on TLS.") + command.Flags().BoolVar(&htst, "hsts", true, "Whether or not we should add a HTTP Secure Transport Security header. This only has effect if secure is enabled.") command.Flags().StringVar(&authMode, "auth-mode", "server", "API server authentication mode. One of: client|server|hybrid") command.Flags().StringVar(&configMap, "configmap", "workflow-controller-configmap", "Name of K8s configmap to retrieve workflow controller configuration") command.Flags().BoolVar(&namespaced, "namespaced", false, "run as namespaced mode") diff --git a/server/apiserver/argoserver.go b/server/apiserver/argoserver.go index 9a1a22851a2a..a5aa7db8e1a9 100644 --- a/server/apiserver/argoserver.go +++ b/server/apiserver/argoserver.go @@ -54,6 +54,7 @@ type argoServer struct { baseHRef string // https://itnext.io/practical-guide-to-securing-grpc-connections-with-go-and-tls-part-1-f63058e9d6d1 tlsConfig *tls.Config + hsts bool namespace string managedNamespace string kubeClientset *kubernetes.Clientset @@ -73,12 +74,14 @@ type ArgoServerOpts struct { // config map name ConfigName string ManagedNamespace string + HSTS bool } func NewArgoServer(opts ArgoServerOpts) *argoServer { return &argoServer{ baseHRef: opts.BaseHRef, tlsConfig: opts.TLSConfig, + hsts: opts.HSTS, namespace: opts.Namespace, managedNamespace: opts.ManagedNamespace, kubeClientset: opts.KubeClientset, @@ -257,7 +260,8 @@ func (as *argoServer) newHTTPServer(ctx context.Context, port int, artifactServe mux.Handle("/api/", gwmux) mux.HandleFunc("/artifacts/", artifactServer.GetArtifact) mux.HandleFunc("/artifacts-by-uid/", artifactServer.GetArtifactByUID) - mux.HandleFunc("/", static.NewFilesServer(as.baseHRef, as.tlsConfig != nil).ServerFiles) + // we only enable HTST if we are insecure mode, otherwise you would never be able access the UI + mux.HandleFunc("/", static.NewFilesServer(as.baseHRef, as.tlsConfig != nil && as.hsts).ServerFiles) return &httpServer } diff --git a/server/static/static.go b/server/static/static.go index 76f3d530f947..1a852d9dc9d0 100644 --- a/server/static/static.go +++ b/server/static/static.go @@ -8,11 +8,11 @@ import ( type FilesServer struct { baseHRef string - secure bool + hsts bool } -func NewFilesServer(baseHRef string, secure bool) *FilesServer { - return &FilesServer{baseHRef, secure} +func NewFilesServer(baseHRef string, hsts bool) *FilesServer { + return &FilesServer{baseHRef, hsts} } func (s *FilesServer) ServerFiles(w http.ResponseWriter, r *http.Request) { @@ -29,7 +29,7 @@ func (s *FilesServer) ServerFiles(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Frame-Options", "DENY") w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-inline'") - if s.secure { + if s.hsts { w.Header().Set("Strict-Transport-Security", "max-age=31536000") }