Files
warmbly/internal/api/middleware/security_headers_test.go
T

77 lines
2.4 KiB
Go

package middleware
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
)
func TestSecurityHeadersAreSet(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(SecurityHeaders())
r.GET("/x", func(c *gin.Context) { c.Status(http.StatusOK) })
w := httptest.NewRecorder()
r.ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/x", nil))
want := map[string]string{
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
"Referrer-Policy": "strict-origin-when-cross-origin",
"Cross-Origin-Opener-Policy": "same-origin",
"Cross-Origin-Resource-Policy": "same-site",
}
for k, v := range want {
if got := w.Header().Get(k); got != v {
t.Errorf("%s = %q, want %q", k, got, v)
}
}
if w.Header().Get("Content-Security-Policy") == "" {
t.Error("a default Content-Security-Policy should be set")
}
}
// HSTS over plain HTTP is ignored by browsers and would pin a self-hosted LAN
// instance to a scheme it does not serve, so it is only sent on a TLS request.
func TestHSTSOnlyOverTLS(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(SecurityHeaders())
r.GET("/x", func(c *gin.Context) { c.Status(http.StatusOK) })
plain := httptest.NewRecorder()
r.ServeHTTP(plain, httptest.NewRequest(http.MethodGet, "/x", nil))
if got := plain.Header().Get("Strict-Transport-Security"); got != "" {
t.Errorf("no HSTS expected over plain HTTP, got %q", got)
}
forwarded := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/x", nil)
req.Header.Set("X-Forwarded-Proto", "https")
r.ServeHTTP(forwarded, req)
if got := forwarded.Header().Get("Strict-Transport-Security"); got == "" {
t.Error("HSTS expected when the edge reports https")
}
}
// A handler that sets its own policy keeps it: the OAuth bouncer pages need
// script-src 'unsafe-inline' for the one script that is the page.
func TestHandlerCSPWins(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(SecurityHeaders())
r.GET("/page", func(c *gin.Context) {
c.Header("Content-Security-Policy", "default-src 'none'; script-src 'unsafe-inline'")
c.Status(http.StatusOK)
})
w := httptest.NewRecorder()
r.ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/page", nil))
if got := w.Header().Get("Content-Security-Policy"); got != "default-src 'none'; script-src 'unsafe-inline'" {
t.Errorf("handler policy should survive, got %q", got)
}
}