Security Audit Fixes: Session fixation prevention, SameSite cookies, audit log redaction, backup integrity, Docker hardening, error sanitization, rate limiting, trusted proxies, and config hardening

This commit is contained in:
backup 2026-09-03 23:55:25 -05:00
commit b587fb87a9
18 changed files with 987 additions and 87 deletions

View file

@ -64,6 +64,10 @@ func (h *AuthHandler) Login(c *gin.Context) {
}
auth.DefaultLoginLimiter.RecordSuccess(clientIP)
// INVALIDATE ANY EXISTING SESSION FOR THIS USER
// Delete any old sessions for this user before creating new one
h.sessionRepo.DeleteByUserID(user.ID)
sessionData, err := auth.NewSessionData(user.ID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create session"})
@ -122,22 +126,12 @@ func (h *AuthHandler) Me(c *gin.Context) {
c.JSON(http.StatusUnauthorized, gin.H{"error": "not authenticated"})
return
}
// Include current CSRF token for bootstrap after page reload
var csrfToken string
if sVal, exists := c.Get("session"); exists {
if s, ok := sVal.(*models.Session); ok && s != nil {
csrfToken = s.CSRFToken
}
}
resp := gin.H{
"id": user.ID,
"username": user.Username,
"email": user.Email,
"role": user.Role,
}
if csrfToken != "" {
resp["csrf_token"] = csrfToken
}
c.JSON(http.StatusOK, resp)
}
@ -151,25 +145,28 @@ func (h *AuthHandler) GetCSRF(c *gin.Context) {
}
func (h *AuthHandler) setSessionCookie(c *gin.Context, sessionID string, expiresAt time.Time) {
c.SetCookie(
SessionCookieName,
sessionID,
int(time.Until(expiresAt).Seconds()),
"/",
h.cookieDomain,
h.cookieSecure,
true, // HttpOnly
)
http.SetCookie(c.Writer, &http.Cookie{
Name: SessionCookieName,
Value: sessionID,
MaxAge: int(time.Until(expiresAt).Seconds()),
Path: "/",
Domain: h.cookieDomain,
Secure: h.cookieSecure,
HttpOnly: true,
SameSite: http.SameSiteStrictMode,
Expires: expiresAt,
})
}
func (h *AuthHandler) clearSessionCookie(c *gin.Context) {
c.SetCookie(
SessionCookieName,
"",
-1,
"/",
h.cookieDomain,
h.cookieSecure,
true,
)
http.SetCookie(c.Writer, &http.Cookie{
Name: SessionCookieName,
Value: "",
MaxAge: -1,
Path: "/",
Domain: h.cookieDomain,
Secure: h.cookieSecure,
HttpOnly: true,
SameSite: http.SameSiteStrictMode,
})
}