CVE-2026-34828
Description
listmonk is a standalone, self-hosted, newsletter and mailing list manager. From version 4.1.0 to before version 6.1.0, a session management vulnerability allows previously issued authenticated sessions to remain valid after sensitive account security changes, specifically password reset and password change. As a result, an attacker who has already obtained a valid session cookie can retain access to the account even after the victim changes or resets their password. This weakens account recovery and session security guarantees. This issue has been patched in version 6.1.0.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/knadh/listmonkGo | >= 1.1.1-0.20241028090858-319053dd7a90, < 1.1.1-0.20260329113754-1b5e8d38c778 | 1.1.1-0.20260329113754-1b5e8d38c778 |
Affected products
1Patches
1db82035d6193Wipe user sessions from DB on password reset/change.
6 files changed · +53 −10
cmd/auth.go+5 −0 modified@@ -687,6 +687,11 @@ func (a *App) doResetPassword(c echo.Context, token, email string) error { return echo.NewHTTPError(http.StatusInternalServerError, a.i18n.T("globals.messages.internalError")) } + // Invalidate all existing sessions for the user after password reset. + if err := a.core.DeleteUserSessions(user.ID, ""); err != nil { + a.log.Printf("error destroying sessions after password reset for user_id=%d: %v", user.ID, err) + } + // Log the user in directly without forcing a manual login right after password change. if err := a.auth.SaveSession(user, "", c); err != nil { return err
cmd/users.go+14 −0 modified@@ -173,6 +173,13 @@ func (a *App) UpdateUser(c echo.Context) error { // Blank out the password hash in the response. user.Password = null.String{} + // If password was changed by admin, destroy all sessions for the given user. + if u.Password.String != "" { + if err := a.core.DeleteUserSessions(id, ""); err != nil { + a.log.Printf("error destroying sessions on admin password change for user_id=%d: %v", id, err) + } + } + // Cache the API token for in-memory, off-DB /api/* request auth. if _, err := cacheUsers(a.core, a.auth); err != nil { return err @@ -263,6 +270,13 @@ func (a *App) UpdateUserProfile(c echo.Context) error { return err } + // If password was changed, destroy all existing sessions for the user except for the current one. + if u.Password.String != "" { + if err := a.core.DeleteUserSessions(user.ID, auth.GetSessionID(c)); err != nil { + a.log.Printf("error destroying sessions after profile password change for user_id=%d: %v", user.ID, err) + } + } + // Blank out the password hash in the response. out.Password = null.String{}
internal/auth/auth.go+10 −0 modified@@ -382,6 +382,16 @@ func (o *Auth) SaveSession(u User, oidcToken string, c echo.Context) error { return nil } +// GetSessionID returns the current session ID from the echo context. +func GetSessionID(c echo.Context) string { + sess, ok := c.Get(SessionKey).(*simplesessions.Session) + if !ok || sess == nil { + return "" + } + + return sess.ID() +} + // validateSession checks if the cookie session is valid (in the DB) and returns the session and user details. func (o *Auth) validateSession(c echo.Context) (*simplesessions.Session, User, error) { // Cookie session.
internal/core/users.go+10 −0 modified@@ -4,6 +4,7 @@ import ( "database/sql" "encoding/json" "net/http" + "strconv" "github.com/knadh/listmonk/internal/auth" "github.com/knadh/listmonk/internal/utils" @@ -132,6 +133,15 @@ func (c *Core) SetTwoFA(id int, twofaType, twofaKey string) error { return nil } +// DeleteUserSessions deletes all sessions for a given user ID, optionally +// excluding a specific session ID (to keep the current session alive). +func (c *Core) DeleteUserSessions(userID int, excludeID string) error { + if _, err := c.q.DeleteUserSessions.Exec(strconv.Itoa(userID), excludeID); err != nil { + return err + } + return nil +} + // DeleteUsers deletes a given user. func (c *Core) DeleteUsers(ids []int) error { res, err := c.q.DeleteUsers.Exec(pq.Array(ids))
models/queries.go+11 −10 modified@@ -117,16 +117,17 @@ type Queries struct { DeleteBouncesBySubscriber *sqlx.Stmt `query:"delete-bounces-by-subscriber"` GetDBInfo string `query:"get-db-info"` - CreateUser *sqlx.Stmt `query:"create-user"` - UpdateUser *sqlx.Stmt `query:"update-user"` - UpdateUserProfile *sqlx.Stmt `query:"update-user-profile"` - UpdateUserLogin *sqlx.Stmt `query:"update-user-login"` - SetUserTwoFA *sqlx.Stmt `query:"set-user-twofa"` - DeleteUsers *sqlx.Stmt `query:"delete-users"` - GetUsers *sqlx.Stmt `query:"get-users"` - GetUser *sqlx.Stmt `query:"get-user"` - GetAPITokens *sqlx.Stmt `query:"get-api-tokens"` - LoginUser *sqlx.Stmt `query:"login-user"` + CreateUser *sqlx.Stmt `query:"create-user"` + UpdateUser *sqlx.Stmt `query:"update-user"` + UpdateUserProfile *sqlx.Stmt `query:"update-user-profile"` + UpdateUserLogin *sqlx.Stmt `query:"update-user-login"` + SetUserTwoFA *sqlx.Stmt `query:"set-user-twofa"` + DeleteUsers *sqlx.Stmt `query:"delete-users"` + GetUsers *sqlx.Stmt `query:"get-users"` + GetUser *sqlx.Stmt `query:"get-user"` + GetAPITokens *sqlx.Stmt `query:"get-api-tokens"` + LoginUser *sqlx.Stmt `query:"login-user"` + DeleteUserSessions *sqlx.Stmt `query:"delete-user-sessions"` CreateRole *sqlx.Stmt `query:"create-role"` GetUserRoles *sqlx.Stmt `query:"get-user-roles"`
queries/users.sql+3 −0 modified@@ -150,3 +150,6 @@ UPDATE users SET loggedin_at=NOW(), avatar=(CASE WHEN $2 != '' THEN $2 ELSE avat -- name: set-user-twofa UPDATE users SET twofa_type=$2::twofa_type, twofa_key=$3, updated_at=NOW() WHERE id=$1; + +-- name: delete-user-sessions +DELETE FROM sessions WHERE data->>'user_id' = $1 AND ($2 = '' OR id != $2);
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/knadh/listmonk/commit/db82035d619348949512dafdaf60c86037cafc9envdPatchWEB
- github.com/knadh/listmonk/security/advisories/GHSA-h5j9-cvrw-v5qhnvdExploitVendor AdvisoryWEB
- github.com/advisories/GHSA-h5j9-cvrw-v5qhghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-34828ghsaADVISORY
- github.com/knadh/listmonk/releases/tag/v6.1.0nvdProductRelease NotesWEB
News mentions
0No linked articles in our index yet.