Fix: Remove socket path leak in fail2ban error responses

- Change _fail2ban_connection_handler() to return generic message instead of
  leaking socket path in HTTP 502 response body
- Change _fail2ban_protocol_handler() to return generic message instead of
  leaking raw exception details in HTTP 502 response body
- Full error details are still logged server-side (error=str(exc)) for debugging
- Update Backend-Development.md with error message hygiene section explaining
  the pattern: generic user-friendly messages in HTTP responses, full details
  in server logs only

Fixes TASK-029: Fail2BanConnectionError leaks socket path in HTTP error responses

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-26 15:21:35 +02:00
parent 5d24780c63
commit b9289a3b0e
3 changed files with 32 additions and 46 deletions

View File

@@ -581,6 +581,36 @@ All domain exceptions raised by services propagate to handlers in `main.py`, ens
2. No duplicated exception-to-HTTP-status mapping logic.
3. Easy to audit all error codes — they are all in one place.
### Error Message Hygiene
HTTP responses must never leak sensitive internal details that aid attackers or expose infrastructure:
- **Never include system paths** in HTTP error messages (e.g., `/var/run/fail2ban/fail2ban.sock`, `/etc/fail2ban/`).
- **Never include raw exception messages** that expose internal parsing or implementation logic.
- **Log full details server-side only** — exception handlers must log `error=str(exc)` with full exception context, but return generic user-friendly messages in the HTTP response.
```python
# ❌ BAD — leaks socket path and internal details to the client
async def _fail2ban_connection_handler(request: Request, exc: Fail2BanConnectionError) -> JSONResponse:
return JSONResponse(
status_code=502,
content={"detail": f"Cannot reach fail2ban: {exc}"}, # exc includes socket path!
)
# ✅ GOOD — generic message in response, full details in server logs
async def _fail2ban_connection_handler(request: Request, exc: Fail2BanConnectionError) -> JSONResponse:
log.warning(
"fail2ban_connection_error",
path=request.url.path,
method=request.method,
error=str(exc), # Full details logged server-side
)
return JSONResponse(
status_code=502,
content={"detail": "Cannot reach the fail2ban service. Check the server status page."},
)
```
---
## 9. Testing