mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-28 03:20:11 +00:00
Add CSRF skip allowlist test
This commit is contained in:
parent
3c9a0ebc58
commit
75710338a3
1 changed files with 77 additions and 0 deletions
77
internal/api/router_csrf_skip_inventory_test.go
Normal file
77
internal/api/router_csrf_skip_inventory_test.go
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRouterCSRFSkipInventory(t *testing.T) {
|
||||
skipPaths := parseCSRFSkipPaths(t)
|
||||
|
||||
expected := sliceToSet(t, csrfSkipAllowlist, "CSRF skip allowlist")
|
||||
actual := sliceToSet(t, skipPaths, "router CSRF skip paths")
|
||||
|
||||
if missing := setDifference(actual, expected); len(missing) > 0 {
|
||||
t.Fatalf("CSRF skip paths missing from allowlist: %s", strings.Join(sortedKeys(missing), ", "))
|
||||
}
|
||||
if stale := setDifference(expected, actual); len(stale) > 0 {
|
||||
t.Fatalf("CSRF skip allowlist contains paths not skipped in router.go: %s", strings.Join(sortedKeys(stale), ", "))
|
||||
}
|
||||
}
|
||||
|
||||
func parseCSRFSkipPaths(t *testing.T) []string {
|
||||
t.Helper()
|
||||
|
||||
_, file, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
t.Fatalf("failed to locate test file path")
|
||||
}
|
||||
routerPath := filepath.Join(filepath.Dir(file), "router.go")
|
||||
data, err := os.ReadFile(routerPath)
|
||||
if err != nil {
|
||||
t.Fatalf("read router.go: %v", err)
|
||||
}
|
||||
src := string(data)
|
||||
|
||||
start := strings.Index(src, "// Check CSRF for state-changing requests")
|
||||
if start == -1 {
|
||||
t.Fatalf("CSRF check block not found in router.go")
|
||||
}
|
||||
end := strings.Index(src[start:], "if strings.HasPrefix(req.URL.Path, \"/api/\") && !skipCSRF")
|
||||
if end == -1 {
|
||||
t.Fatalf("CSRF enforcement block not found in router.go")
|
||||
}
|
||||
block := src[start : start+end]
|
||||
|
||||
re := regexp.MustCompile(`req\.URL\.Path == "([^"]+)"`)
|
||||
matches := re.FindAllStringSubmatch(block, -1)
|
||||
if len(matches) == 0 {
|
||||
t.Fatalf("no CSRF skip paths found in router.go")
|
||||
}
|
||||
|
||||
paths := make([]string, 0, len(matches))
|
||||
seen := map[string]struct{}{}
|
||||
for _, match := range matches {
|
||||
path := match[1]
|
||||
if _, ok := seen[path]; ok {
|
||||
continue
|
||||
}
|
||||
seen[path] = struct{}{}
|
||||
paths = append(paths, path)
|
||||
}
|
||||
sort.Strings(paths)
|
||||
return paths
|
||||
}
|
||||
|
||||
var csrfSkipAllowlist = []string{
|
||||
"/api/login",
|
||||
"/api/security/apply-restart",
|
||||
"/api/security/quick-setup",
|
||||
"/api/security/validate-bootstrap-token",
|
||||
"/api/setup-script-url",
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue