Commit d3a5f39
sec(handlers,middleware): escape renderAuthError HTML + drop secret-length leak in e2e bypass log (#173)
Two defense-in-depth security fixes uncovered during the 2026-05-29 api +
common security audit (see /tmp/qa-session/shared/SEC-INBOX.md).
SEC-API FINDING-23 — renderAuthError HTML interpolation (P2 hardening, CWE-79)
renderAuthError is the only HTML-emitting handler in api. It took
(headline, detail string) and fmt.Sprintf'd both into a <!DOCTYPE html>
template without escaping. Every existing caller (24 sites across
auth.go + magic_link.go) passes static literals so there is no live
exploit today, but the function is unsafe-by-default — any future caller
that passes a user-influenced value (OAuth profile name, JWT email
claim, raw upstream error message) silently introduces reflected XSS on
the api.instanode.dev origin. Cookies for that host (oauth_state, future
session cookies, etc.) would be stealable.
Apply html.EscapeString to both args at the sink. The function is now
safe for every caller regardless of input provenance — they don't have
to remember to escape. Adds one new regression test
TestAuth_RenderAuthError_HTMLEscapesPayload that asserts the literal
<script>, </script>, and <img src=x payloads do not survive into the
response body, and that their escaped forms (<script> etc.) do.
SEC-API FINDING-26 — e2e bypass mismatch logs expected secret length (P3, CWE-200)
middleware.e2eTokenAccepted's mismatch path logged got_len, expected_len,
and got_prefix. Two info-disclosure problems:
- expected_len leaks the byte-length of E2E_TEST_TOKEN to anyone with
log read access (NR Logs / log-aggregation breach). Narrows brute-
force search space if the operator picked a short token.
- got_prefix echoes the attacker's own guess into long-term log
storage, attesting the env var is configured in prod and enabling
correlation-grep against future attacker payloads.
Drop expected_len and got_prefix. Keep got_len — the attacker already
knows the length of their own input, so this leaks nothing new while
still letting an SRE distinguish "wrong-content" from "missing/malformed"
failure modes.
Production LOC delta: 24 lines (well under 50). No behavioural change
on the happy path of either function. Existing tests pass; one new
test added.
Co-authored-by: instanode-sec-audit <security@instanode.dev>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent f2fb140 commit d3a5f39
3 files changed
Lines changed: 61 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| |||
946 | 947 | | |
947 | 948 | | |
948 | 949 | | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
949 | 959 | | |
950 | 960 | | |
951 | 961 | | |
| |||
956 | 966 | | |
957 | 967 | | |
958 | 968 | | |
959 | | - | |
| 969 | + | |
960 | 970 | | |
961 | 971 | | |
962 | 972 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
271 | 271 | | |
272 | 272 | | |
273 | 273 | | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
274 | 314 | | |
275 | 315 | | |
276 | 316 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
127 | 136 | | |
128 | | - | |
129 | | - | |
| 137 | + | |
130 | 138 | | |
131 | 139 | | |
132 | 140 | | |
0 commit comments