mirror of
https://github.com/juanfont/headscale.git
synced 2026-11-04 20:49:24 +09:00
82 lines
3.8 KiB
Go
82 lines
3.8 KiB
Go
package hscontrol
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestSecurityHeaders(t *testing.T) {
|
|
handler := securityHeaders(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
}))
|
|
|
|
rec := httptest.NewRecorder()
|
|
req := httptest.NewRequestWithContext(context.Background(), http.MethodGet, "/", nil)
|
|
handler.ServeHTTP(rec, req)
|
|
|
|
h := rec.Result().Header
|
|
assert.Equal(t, "DENY", h.Get("X-Frame-Options"))
|
|
assert.Equal(t, "frame-ancestors 'none'", h.Get("Content-Security-Policy"))
|
|
assert.Equal(t, "nosniff", h.Get("X-Content-Type-Options"))
|
|
assert.Equal(t, "no-referrer", h.Get("Referrer-Policy"))
|
|
}
|
|
|
|
func TestDebugHostGuard(t *testing.T) {
|
|
app := createTestApp(t)
|
|
app.cfg.ServerURL = "https://Control.Example.COM:443/headscale"
|
|
app.cfg.MetricsAddr = "Debug.Internal:9090"
|
|
app.cfg.BaseDomain = "tailnet.invalid"
|
|
handler := app.debugHTTPServer().Handler
|
|
|
|
for _, tt := range []struct {
|
|
name string
|
|
host string
|
|
path string
|
|
status int
|
|
}{
|
|
{name: "localhost", host: "localhost:9090", path: "/debug/", status: http.StatusOK},
|
|
{name: "localhost case and dot", host: "LOCALhost.", path: "/debug/", status: http.StatusOK},
|
|
{name: "IPv4", host: "127.0.0.1:9090", path: "/debug/", status: http.StatusOK},
|
|
{name: "IPv6", host: "[::1]", path: "/debug/", status: http.StatusOK},
|
|
{name: "IPv6 port", host: "[::1]:9090", path: "/debug/", status: http.StatusOK},
|
|
{name: "tailnet IP", host: "100.64.0.1:9090", path: "/debug/", status: http.StatusOK},
|
|
{name: "private IP", host: "192.168.0.1:9090", path: "/debug/", status: http.StatusOK},
|
|
{name: "server URL host", host: "CoNtRoL.ExAmPlE.CoM.:9090", path: "/debug/", status: http.StatusOK},
|
|
{name: "metrics listen host", host: "DEBUG.INTERNAL.:9090", path: "/debug/", status: http.StatusOK},
|
|
{name: "unknown host", host: "unknown.example", path: "/debug/", status: http.StatusForbidden},
|
|
{name: "localhost suffix", host: "localhost.remote.example", path: "/debug/", status: http.StatusForbidden},
|
|
{name: "server suffix", host: "control.example.com.remote", path: "/debug/", status: http.StatusForbidden},
|
|
{name: "empty host", host: "", path: "/debug/", status: http.StatusForbidden},
|
|
{name: "base domain", host: "tailnet.invalid", path: "/debug/", status: http.StatusForbidden},
|
|
{name: "base domain child", host: "node.tailnet.invalid", path: "/debug/", status: http.StatusForbidden},
|
|
{name: "custom debug handler", host: "unknown.example", path: "/debug/overview", status: http.StatusForbidden},
|
|
{name: "pprof", host: "unknown.example", path: "/debug/pprof/", status: http.StatusForbidden},
|
|
{name: "statsviz", host: "unknown.example", path: "/debug/statsviz/", status: http.StatusForbidden},
|
|
{name: "statsviz websocket", host: "unknown.example", path: "/debug/statsviz/ws", status: http.StatusForbidden},
|
|
{name: "whole mux", host: "unknown.example", path: "/", status: http.StatusForbidden},
|
|
{name: "metrics any host", host: "unknown.example", path: "/metrics", status: http.StatusOK},
|
|
{name: "metrics empty host", host: "", path: "/metrics", status: http.StatusOK},
|
|
{name: "metrics query", host: "unknown.example", path: "/metrics?x=1", status: http.StatusOK},
|
|
{name: "metrics slash", host: "unknown.example", path: "/metrics/", status: http.StatusForbidden},
|
|
} {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
req := httptest.NewRequestWithContext(t.Context(), http.MethodGet, tt.path, nil)
|
|
req.Host = tt.host
|
|
req.RemoteAddr = "127.0.0.1:1234"
|
|
rec := httptest.NewRecorder()
|
|
handler.ServeHTTP(rec, req)
|
|
|
|
assert.Equal(t, tt.status, rec.Code)
|
|
assert.Equal(t, "DENY", rec.Header().Get("X-Frame-Options"))
|
|
|
|
if tt.status == http.StatusForbidden {
|
|
assert.Contains(t, rec.Body.String(), "localhost")
|
|
}
|
|
})
|
|
}
|
|
}
|