Commit 786cffa
committed
fix(csrf): Replace gorilla/csrf with net/http.CrossOriginProtection
govulncheck reported Harbor's own code as affected by CVE-2025-24358, with a
call trace through server/middleware/csrf/csrf.go. The fix is gorilla/csrf
v1.7.3, and we were pinned below it on purpose: v1.7.3 broke HTTP-only logins
(goharbor/harbor#22010), upstream reverted, and .github/renovate.json was taught
to block the bump. There was no way out of that while the dependency stayed.
Lifting the pin was tried first and does not work. v1.7.3 reconstructs the
origin it expects from a presumed scheme plus the Host header, and neither
survives a proxy. Against a real HTTP deployment behind Harbor's own nginx:
- nginx sends 'proxy_set_header Host $host', which drops the port, so the
library compared 192.168.0.5 against the browser's 192.168.0.5:8099 and
answered 403 even with the plaintext flag set.
- The plaintext flag is one global boolean off EXT_ENDPOINT's scheme. On a
deployment answering as us./eu./harbor.dev over https with EXT_ENDPOINT on
http, every ingress returned 403. One flag cannot describe N ingresses.
CrossOriginProtection judges each request on the origin the browser actually
used. Sec-Fetch-Site decides it, and no configured endpoint, Host or scheme
enters the decision, so several ingresses on different schemes behind
Host-rewriting proxies all work with nothing to configure. All four hostnames
answer 200 in that same deployment.
It also closes the attack the token scheme let through. A sibling subdomain is
same-site, so SameSite=Strict still sent _gorilla_csrf and the subdomain could
write cookies on the parent domain, making both halves of the double submit
attacker-controlled; only the Origin check stood in the way, and CVE-2025-24358
is that the check never ran. That request is now refused.
One gap is closed beyond what the library does. CrossOriginProtection admits a
request carrying neither Sec-Fetch-Site nor Origin, reading it as non-browser
traffic. csrfSkipper has already excused the registry, API and service routes
that non-browser clients use, so an unsafe request arriving without either
header is refused instead, matching the token scheme which rejected any write
presenting no token.
gorilla/csrf and gorilla/securecookie leave go.mod and the Renovate pin goes
with them. govulncheck drops from one affected vulnerability to none, and no
longer reports CVE-2025-47909 either, which has no fix in any release.
csrfSkipper is untouched. CSRF_KEY is now inert and the portal's token
interceptor is dead code; both degrade quietly and are removed separately rather
than folded into a security fix.
Signed-off-by: Prasanth Baskar <prasanth@8gears.com>1 parent fdf2dbd commit 786cffa
5 files changed
Lines changed: 201 additions & 144 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
134 | 134 | | |
135 | 135 | | |
136 | 136 | | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
144 | 137 | | |
145 | 138 | | |
146 | 139 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | | - | |
40 | | - | |
41 | 39 | | |
42 | 40 | | |
43 | 41 | | |
| |||
154 | 152 | | |
155 | 153 | | |
156 | 154 | | |
157 | | - | |
158 | 155 | | |
159 | 156 | | |
160 | 157 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3767 | 3767 | | |
3768 | 3768 | | |
3769 | 3769 | | |
3770 | | - | |
3771 | | - | |
3772 | 3770 | | |
3773 | 3771 | | |
3774 | 3772 | | |
| |||
3860 | 3858 | | |
3861 | 3859 | | |
3862 | 3860 | | |
3863 | | - | |
3864 | | - | |
3865 | 3861 | | |
3866 | 3862 | | |
3867 | 3863 | | |
3868 | 3864 | | |
3869 | 3865 | | |
3870 | 3866 | | |
3871 | | - | |
3872 | | - | |
3873 | 3867 | | |
3874 | 3868 | | |
3875 | 3869 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | | - | |
22 | 21 | | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | 22 | | |
27 | | - | |
28 | 23 | | |
29 | 24 | | |
30 | 25 | | |
31 | 26 | | |
32 | 27 | | |
33 | 28 | | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
38 | 32 | | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
44 | 36 | | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
51 | 50 | | |
52 | | - | |
53 | 51 | | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
58 | 59 | | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
| 60 | + | |
64 | 61 | | |
65 | 62 | | |
66 | | - | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
67 | 72 | | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
79 | 77 | | |
80 | 78 | | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
| 79 | + | |
| 80 | + | |
90 | 81 | | |
91 | 82 | | |
92 | 83 | | |
| |||
100 | 91 | | |
101 | 92 | | |
102 | 93 | | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
0 commit comments