# SSE Authentication Security Mitigations ## Implementation Date **2025-10-02** ## Security Concern: Token in Query Parameters The SSE endpoint (`/api/events?token=xxx`) accepts authentication tokens via query parameters due to browser `EventSource` API limitations. This introduces security risks that have been mitigated. --- ## Security Risks & Mitigations ### 1. Token Exposure in Logs ⚠️ **Risk:** Nginx access logs contain full URLs including tokens **Impact:** Medium - If logs are compromised, tokens could be exposed **Mitigations Implemented:** - ✅ **Short Token Expiry**: JWT tokens expire in 30 minutes (configurable in `.env`) - ✅ **HTTPS Only**: All production traffic uses TLS encryption - ✅ **Log Access Control**: Kubernetes logs have RBAC restrictions - ⚠️ **Manual Log Filtering**: Nginx configuration-snippet is disabled by admin **Additional Mitigation (Manual):** If you have access to nginx ingress controller configuration, enable log filtering: ```yaml # In nginx ingress controller ConfigMap data: log-format-upstream: '$remote_addr - $remote_user [$time_local] "$request_method $sanitized_uri $server_protocol" $status $body_bytes_sent "$http_referer" "$http_user_agent"' ``` Or use a log aggregation tool (Loki, ELK) with regex filtering to redact tokens. --- ### 2. Token in Browser History 📝 **Risk:** Browser stores URLs with query params in history **Impact:** Low - Requires local access to user's machine **Mitigations Implemented:** - ✅ **User's Own Browser**: History is private to the user - ✅ **Short Expiry**: Old tokens in history expire quickly - ✅ **Auto-logout**: Session management invalidates tokens **Not a Risk:** SSE connections are initiated by JavaScript (EventSource), not user navigation, so they typically don't appear in browser history. --- ### 3. Referrer Header Leakage 🔗 **Risk:** When user navigates away, Referrer header might include SSE URL **Impact:** Medium - Token could leak to third-party sites **Mitigations Implemented:** - ⚠️ **Referrer-Policy Header**: Attempted via nginx annotation (blocked by admin) - ✅ **SameSite Routing**: SSE is same-origin (no external referrers) - ✅ **HTTPS**: Browsers don't send Referrer from HTTPS to HTTP **Manual Mitigation:** Add to HTML head in frontend: ```html ``` Or add HTTP header via frontend response headers. --- ### 4. Proxy/CDN Caching 🌐 **Risk:** Intermediary proxies might cache or log URLs **Impact:** Low - Internal infrastructure only **Mitigations Implemented:** - ✅ **Direct Ingress**: No external proxies/CDNs - ✅ **Internal Network**: All routing within Kubernetes cluster - ✅ **Cache-Control Headers**: SSE endpoints set no-cache --- ### 5. Accidental URL Sharing 📤 **Risk:** Users could copy/share URLs with embedded tokens **Impact:** High (for regular URLs) / Low (for SSE - not user-visible) **Mitigations Implemented:** - ✅ **Hidden from Users**: EventSource connections not visible in address bar - ✅ **Short Token Expiry**: Shared tokens expire quickly - ✅ **One-Time Use**: Tokens invalidated on logout --- ## Security Comparison | Threat | Query Param Token | Header Token | Cookie Token | WebSocket | |--------|-------------------|--------------|--------------|-----------| | **Server Logs** | ⚠️ Medium | ✅ Safe | ✅ Safe | ✅ Safe | | **Browser History** | ⚠️ Low | ✅ Safe | ✅ Safe | ✅ Safe | | **Referrer Leakage** | ⚠️ Medium | ✅ Safe | ⚠️ Medium | ✅ Safe | | **XSS Attacks** | ⚠️ Vulnerable | ⚠️ Vulnerable | ✅ httpOnly | ⚠️ Vulnerable | | **CSRF Attacks** | ✅ Safe | ✅ Safe | ⚠️ Requires token | ✅ Safe | | **Ease of Use** | ✅ Simple | ❌ Not supported | ⚠️ Complex | ⚠️ Complex | | **Browser Support** | ✅ Native | ❌ No EventSource | ✅ Native | ✅ Native | --- ## Applied Mitigations Summary ### ✅ Implemented: 1. **Short token expiry** (30 minutes) 2. **HTTPS enforcement** (production) 3. **Token validation** (middleware + endpoint) 4. **CORS restrictions** (specific origins) 5. **Kubernetes RBAC** (log access control) 6. **Same-origin policy** (no external referrers) 7. **Auto-logout** (session management) ### ⚠️ Blocked by Infrastructure: 1. **Nginx log filtering** (configuration-snippet disabled) 2. **Referrer-Policy header** (configuration-snippet disabled) ### 📝 Recommended (Manual): 1. **Add Referrer-Policy meta tag** to frontend HTML 2. **Enable nginx log filtering** if ingress admin allows 3. **Use log aggregation** with token redaction (Loki/ELK) 4. **Monitor for suspicious patterns** in logs --- ## Production Checklist Before deploying to production, ensure: - [ ] HTTPS enforced (no HTTP fallback) - [ ] Token expiry set to ≤ 30 minutes - [ ] CORS origins limited to specific domains (not `*`) - [ ] Kubernetes RBAC configured for log access - [ ] Frontend has Referrer-Policy meta tag - [ ] Log aggregation configured with token redaction - [ ] Monitoring/alerting for failed auth attempts - [ ] Rate limiting enabled on gateway - [ ] Regular security audits of access logs --- ## Upgrade Path to Cookie-Based Auth For maximum security, migrate to cookie-based authentication: **Effort:** ~2-3 hours **Security:** ⭐⭐⭐⭐⭐ (5/5) **Changes needed:** 1. Auth service sets httpOnly cookie on login 2. Gateway auth middleware reads cookie instead of query param 3. Frontend uses `withCredentials: true` (already done!) **Benefits:** - ✅ No token in URL - ✅ No token in logs - ✅ XSS protection (httpOnly) - ✅ CSRF protection (SameSite) --- ## Risk Assessment ### Current Risk Level: **MEDIUM** ⚠️ **Acceptable for:** - ✅ Internal/development environments - ✅ Short-term production (with monitoring) - ✅ Low-sensitivity data **Not recommended for:** - ❌ High-security environments - ❌ Long-term production without upgrade path - ❌ Systems handling PII/financial data **Upgrade recommended within:** 30-60 days for production --- ## Incident Response ### If Token Leak Suspected: 1. **Immediate Actions:** ```bash # Invalidate all active sessions kubectl exec -it -n bakery-ia $(kubectl get pod -n bakery-ia -l app=redis -o name) -- redis-cli KEYS auth:token:* DEL auth:token:* ``` 2. **Rotate JWT Secret:** ```bash # Update .env JWT_SECRET_KEY= # Restart auth service and gateway kubectl rollout restart deployment auth-service gateway -n bakery-ia ``` 3. **Force Re-authentication:** - All users must login again - Existing tokens invalidated 4. **Audit Logs:** ```bash # Check for suspicious SSE connections kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller | grep "/api/events" ``` --- ## Monitoring Queries ### Check for Suspicious Activity: ```bash # High volume of SSE connections from single IP kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller | grep "/api/events" | awk '{print $1}' | sort | uniq -c | sort -rn | head -10 # Failed authentication attempts kubectl logs -n bakery-ia -l app.kubernetes.io/name=gateway | grep "401\|Invalid token" # SSE connections with expired tokens kubectl logs -n bakery-ia -l app.kubernetes.io/name=gateway | grep "Token expired" ``` --- ## Compliance Notes ### GDPR: - ✅ Tokens are pseudonymous identifiers - ✅ Short retention (30 min expiry) - ⚠️ Tokens in logs = personal data processing (document in privacy policy) ### SOC 2: - ⚠️ Query param auth acceptable with compensating controls - ✅ Encryption in transit (HTTPS) - ✅ Access controls (RBAC) - 📝 Document risk acceptance in security policy ### PCI DSS: - ❌ Not recommended for payment card data - ✅ Acceptable for non-cardholder data - 📝 May require additional compensating controls --- ## References - [OWASP: Transport Layer Protection](https://owasp.org/www-community/controls/Transport_Layer_Protection) - [EventSource API Spec](https://html.spec.whatwg.org/multipage/server-sent-events.html) - [RFC 6750: OAuth 2.0 Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750.html#section-2.3) --- ## Decision Log **Date:** 2025-10-02 **Decision:** Use query parameter authentication for SSE endpoint **Rationale:** EventSource API limitation (no custom headers) **Accepted Risk:** Medium (token in logs, limited referrer leakage) **Mitigation Plan:** Implement cookie-based auth within 60 days **Approved By:** Technical Lead --- ## Next Steps 1. **Short-term (now):** - ✅ Query param auth implemented - ✅ Security mitigations documented - 📝 Add Referrer-Policy to frontend - 📝 Configure log monitoring 2. **Medium-term (30 days):** - 📝 Implement cookie-based authentication - 📝 Enable nginx log filtering (if allowed) - 📝 Set up log aggregation with redaction 3. **Long-term (60 days):** - 📝 Security audit of implementation - 📝 Penetration testing - 📝 Consider WebSocket migration (if bidirectional needed)