carlos / movement Public

Clone
git clone https://amadan.net/carlos/movement

Plain git — no account needed to clone.

Download

Download this file

1package movementtest
2
3import (
4 "strings"
5 "testing"
6
7 movement "amadan.net/carlos/movement/internal/movement"
8)
9
10// The app's own Content-Security-Policy broke its own admin sign-in, and did
11// it silently: the POST succeeded, the 303 to the provider was correct, and
12// the browser refused to follow it. form-action governs the whole redirect
13// chain a form submission starts, not only where the form posts.
14//
15// The only evidence was a line in somebody's console. That is why this is a
16// test: nothing server-side fails, so nothing else would ever catch it.
17func TestSigninProviderIsAllowedByFormAction(t *testing.T) {
18 csp := movement.CSP()
19
20 formAction := ""
21 for _, d := range strings.Split(csp, ";") {
22 if d = strings.TrimSpace(d); strings.HasPrefix(d, "form-action") {
23 formAction = d
24 }
25 }
26 if formAction == "" {
27 t.Fatal("no form-action directive at all, which is more permissive than the default")
28 }
29 if !strings.Contains(formAction, "'self'") {
30 t.Error("form-action must still allow this app's own forms")
31 }
32 if !strings.Contains(formAction, "https://keymail.dev") {
33 t.Errorf("the sign-in provider is not in form-action, so the browser "+
34 "will refuse the redirect that starts the ceremony: %q", formAction)
35 }
36}
37
38// Widening one directive must not quietly widen the rest. Everything except
39// form-action stays exactly as strict as the framework's default.
40func TestNothingElseInThePolicyWasWidened(t *testing.T) {
41 csp := movement.CSP()
42
43 for _, want := range []string{
44 "default-src 'self'",
45 "style-src 'self' 'unsafe-inline'",
46 "img-src 'self' data:",
47 "frame-ancestors 'none'",
48 "base-uri 'self'",
49 } {
50 if !strings.Contains(csp, want) {
51 t.Errorf("the policy no longer carries %q", want)
52 }
53 }
54 if strings.Contains(csp, "script-src") {
55 t.Error("scripts have been given their own directive; they should stay " +
56 "under default-src 'self'")
57 }
58 if strings.Contains(csp, "unsafe-eval") || strings.Contains(csp, "*") {
59 t.Error("the policy contains a wildcard or unsafe-eval")
60 }
61}
62