Skip to content
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

feat(ui): Enable CSP, HSTS, X-Frame-Options. Fixes #2760, #1376, #2761 #2971

Merged
merged 3 commits into from
May 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/argo/commands/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -86,6 +87,7 @@ See %s`, help.ArgoSever),
opts := apiserver.ArgoServerOpts{
BaseHRef: baseHRef,
TLSConfig: tlsConfig,
HSTS: htst,
Namespace: namespace,
WfClientSet: wflientset,
KubeClientset: kubeConfig,
Expand Down Expand Up @@ -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")
Expand Down
6 changes: 5 additions & 1 deletion server/apiserver/argoserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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).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
}

Expand Down
11 changes: 9 additions & 2 deletions server/static/static.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import (

type FilesServer struct {
baseHRef string
hsts bool
}

func NewFilesServer(baseHRef string) *FilesServer {
return &FilesServer{baseHRef}
func NewFilesServer(baseHRef string, hsts bool) *FilesServer {
return &FilesServer{baseHRef, hsts}
}

func (s *FilesServer) ServerFiles(w http.ResponseWriter, r *http.Request) {
Expand All @@ -26,6 +27,12 @@ func (s *FilesServer) ServerFiles(w http.ResponseWriter, r *http.Request) {
w = &responseRewriter{ResponseWriter: w, old: []byte(`<base href="/">`), new: []byte(fmt.Sprintf(`<base href="%s">`, s.baseHRef))}
}

w.Header().Set("X-Frame-Options", "DENY")
w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-inline'")
if s.hsts {
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)
}
Binary file added ui/src/app/assets/fonts/Heebo-Regular.ttf
Binary file not shown.
18 changes: 18 additions & 0 deletions ui/src/app/assets/styles/heebo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* hebrew */
@font-face {
font-family: 'Heebo';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Heebo'), local('Heebo-Regular'), url(../fonts/Heebo-Regular.ttf) format('ttf');
unicode-range: U+0590-05FF, U+20AA, U+25CC, U+FB1D-FB4F;
}
/* latin */
@font-face {
font-family: 'Heebo';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Heebo'), local('Heebo-Regular'), url(../fonts/Heebo-Regular.ttf) format('ttf');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
2 changes: 1 addition & 1 deletion ui/src/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta charset="UTF-8">
<title>Argo</title>
<base href="/">
<link href="https://fonts.googleapis.com/css?family=Heebo:300,400,500,700" rel="stylesheet">
<link href="assets/styles/heebo.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex">
<link rel="icon" type="image/png" href="assets/favicon/favicon-32x32.png" sizes="32x32">
Expand Down
2 changes: 2 additions & 0 deletions ui/src/app/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down