Added HTTP security headers to web.go (#3583)
Signed-off-by: Eric Valenzuela <evalenzuela@thousandeyes.com>
This commit is contained in:
parent
6a5f949317
commit
c207920500
15
web/web.go
15
web/web.go
|
@ -71,6 +71,17 @@ import (
|
||||||
|
|
||||||
var localhostRepresentations = []string{"127.0.0.1", "localhost"}
|
var localhostRepresentations = []string{"127.0.0.1", "localhost"}
|
||||||
|
|
||||||
|
// secureHeadersMiddleware adds common HTTP security headers to responses.
|
||||||
|
func secureHeadersMiddleware(h http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Add("X-XSS-Protection", "1; mode=block")
|
||||||
|
w.Header().Add("X-Content-Type-Options", "nosniff")
|
||||||
|
w.Header().Add("X-Frame-Options", "SAMEORIGIN")
|
||||||
|
w.Header().Add("Content-Security-Policy", "frame-ancestors 'self'")
|
||||||
|
h.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
requestDuration = prometheus.NewHistogramVec(
|
requestDuration = prometheus.NewHistogramVec(
|
||||||
prometheus.HistogramOpts{
|
prometheus.HistogramOpts{
|
||||||
|
@ -478,8 +489,10 @@ func (h *Handler) Run(ctx context.Context) error {
|
||||||
|
|
||||||
errlog := stdlog.New(log.NewStdlibAdapter(level.Error(h.logger)), "", 0)
|
errlog := stdlog.New(log.NewStdlibAdapter(level.Error(h.logger)), "", 0)
|
||||||
|
|
||||||
|
withSecureHeaders := nethttp.Middleware(opentracing.GlobalTracer(), secureHeadersMiddleware(mux), operationName)
|
||||||
|
|
||||||
httpSrv := &http.Server{
|
httpSrv := &http.Server{
|
||||||
Handler: nethttp.Middleware(opentracing.GlobalTracer(), mux, operationName),
|
Handler: withSecureHeaders,
|
||||||
ErrorLog: errlog,
|
ErrorLog: errlog,
|
||||||
ReadTimeout: h.options.ReadTimeout,
|
ReadTimeout: h.options.ReadTimeout,
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,54 @@ func TestGlobalURL(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEndpointHeaders(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
dbDir, err := ioutil.TempDir("", "tsdb-ready")
|
||||||
|
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
|
defer os.RemoveAll(dbDir)
|
||||||
|
|
||||||
|
db, err := libtsdb.Open(dbDir, nil, nil, nil)
|
||||||
|
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
|
opts := &Options{
|
||||||
|
ListenAddress: ":9095",
|
||||||
|
ReadTimeout: 30 * time.Second,
|
||||||
|
MaxConnections: 512,
|
||||||
|
Context: nil,
|
||||||
|
Storage: &tsdb.ReadyStorage{},
|
||||||
|
QueryEngine: nil,
|
||||||
|
RuleManager: nil,
|
||||||
|
Notifier: nil,
|
||||||
|
RoutePrefix: "/",
|
||||||
|
EnableAdminAPI: true,
|
||||||
|
TSDB: func() *libtsdb.DB { return db },
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.Flags = map[string]string{}
|
||||||
|
|
||||||
|
webHandler := New(nil, opts)
|
||||||
|
go func() {
|
||||||
|
err := webHandler.Run(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("Can't start webhandler error %s", err))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
|
||||||
|
resp, err := http.Get("http://localhost:9095/version")
|
||||||
|
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
testutil.Equals(t, "1; mode=block", resp.Header.Get("X-XSS-Protection"))
|
||||||
|
testutil.Equals(t, "nosniff", resp.Header.Get("X-Content-Type-Options"))
|
||||||
|
testutil.Equals(t, "SAMEORIGIN", resp.Header.Get("X-Frame-Options"))
|
||||||
|
testutil.Equals(t, "frame-ancestors 'self'", resp.Header.Get("Content-Security-Policy"))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestReadyAndHealthy(t *testing.T) {
|
func TestReadyAndHealthy(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
dbDir, err := ioutil.TempDir("", "tsdb-ready")
|
dbDir, err := ioutil.TempDir("", "tsdb-ready")
|
||||||
|
|
Loading…
Reference in New Issue