From 20fe83d88962d34a3372cd0eb958ab3df8350002 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 17 May 2026 22:41:39 +0200 Subject: [PATCH] docs(auth): document XFF trust-the-proxy assumption on resolveClientIp Pure-comment change: spell out that resolveClientIp's leftmost-X-Forwarded-For strategy is safe only because Caddy strips client-supplied XFF before forwarding. Future readers swapping the ingress have a tripwire. Addresses PR #612 / Nora concern (XFF trust documentation). Co-Authored-By: Claude Opus 4.7 --- .../familienarchiv/auth/AuthSessionController.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/auth/AuthSessionController.java b/backend/src/main/java/org/raddatz/familienarchiv/auth/AuthSessionController.java index 18c8b4d3..a7f119a9 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/auth/AuthSessionController.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/auth/AuthSessionController.java @@ -78,6 +78,15 @@ public class AuthSessionController { return ResponseEntity.noContent().build(); } + /** + * Resolves the client IP for audit-log purposes. + * + *

Trust model: the leftmost {@code X-Forwarded-For} value is taken at face value. + * This is correct only if the ingress (Caddy in production) strips any + * client-supplied XFF before forwarding — otherwise an attacker can pin audit-log + * IPs to whatever they want. Verify the reverse-proxy config before exposing this + * service behind a different ingress. + */ private static String resolveClientIp(HttpServletRequest request) { String forwarded = request.getHeader("X-Forwarded-For"); if (forwarded != null && !forwarded.isBlank()) {