Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-41041: Merge pull request from GHSA-3fqm-frhg-7c85 · Graylog2/graylog2-server@bb88f3d

Graylog is a free and open log management platform. In a multi-node Graylog cluster, after a user has explicitly logged out, a user session may still be used for API requests until it has reached its original expiry time. Each node maintains an in-memory cache of user sessions. Upon a cache-miss, the session is loaded from the database. After that, the node operates solely on the cached session. Modifications to sessions will update the cached version as well as the session persisted in the database. However, each node maintains their isolated version of the session. When the user logs out, the session is removed from the node-local cache and deleted from the database. The other nodes will however still use the cached session. These nodes will only fail to accept the session id if they intent to update the session in the database. They will then notice that the session is gone. This is true for most API requests originating from user interaction with the Graylog UI because these will lead to an update of the session’s “last access” timestamp. If the session update is however prevented by setting the X-Graylog-No-Session-Extension:true header in the request, the node will consider the (cached) session valid until the session is expired according to its timeout setting. No session identifiers are leaked. After a user has logged out, the UI shows the login screen again, which gives the user the impression that their session is not valid anymore. However, if the session becomes compromised later, it can still be used to perform API requests against the Graylog cluster. The time frame for this is limited to the configured session lifetime, starting from the time when the user logged out. This issue has been addressed in versions 5.0.9 and 5.1.3. Users are advised to upgrade.

CVE
#apache#auth#mongo

Expand Up @@ -28,14 +28,12 @@ import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import org.apache.commons.lang.StringUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.annotation.RequiresAuthentication; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.permission.WildcardPermission; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.session.Session; import org.apache.shiro.session.mgt.DefaultSessionManager; import org.apache.shiro.session.mgt.eis.SessionDAO; import org.apache.shiro.subject.Subject; import org.graylog.security.UserContext; import org.graylog.security.permissions.GRNPermission; import org.graylog2.audit.AuditEventTypes; Expand All @@ -61,6 +59,7 @@ import org.graylog2.security.AccessTokenService; import org.graylog2.security.MongoDBSessionService; import org.graylog2.security.MongoDbSession; import org.graylog2.security.UserSessionTerminationService; import org.graylog2.shared.rest.resources.RestResource; import org.graylog2.shared.security.RestPermissions; import org.graylog2.shared.users.ChangeUserRequest; Expand Down Expand Up @@ -137,6 +136,8 @@ public class UsersResource extends RestResource { private final RoleService roleService; private final MongoDBSessionService sessionService; private final SearchQueryParser searchQueryParser; private final UserSessionTerminationService sessionTerminationService; private final DefaultSecurityManager securityManager;
protected static final ImmutableMap<String, SearchQueryField> SEARCH_FIELD_MAPPING = ImmutableMap.<String, SearchQueryField>builder() .put(UserOverviewDTO.FIELD_ID, SearchQueryField.create("_id", SearchQueryField.Type.OBJECT_ID)) Expand All @@ -150,12 +151,15 @@ public UsersResource(UserManagementService userManagementService, PaginatedUserService paginatedUserService, AccessTokenService accessTokenService, RoleService roleService, MongoDBSessionService sessionService) { MongoDBSessionService sessionService, UserSessionTerminationService sessionTerminationService, DefaultSecurityManager securityManager) { this.userManagementService = userManagementService; this.accessTokenService = accessTokenService; this.roleService = roleService; this.sessionService = sessionService; this.paginatedUserService = paginatedUserService; this.sessionTerminationService = sessionTerminationService; this.securityManager = securityManager; this.searchQueryParser = new SearchQueryParser(UserOverviewDTO.FIELD_FULL_NAME, SEARCH_FIELD_MAPPING); }
Expand Down Expand Up @@ -439,8 +443,8 @@ public void changeUser(@ApiParam(name = "userId", value = "The ID of the user to if (isPermitted(“*”)) { final Long sessionTimeoutMs = cr.sessionTimeoutMs(); if (Objects.nonNull(sessionTimeoutMs) && sessionTimeoutMs != 0 && (user.getSessionTimeoutMs() != sessionTimeoutMs)) { updateExistingSession(user, sessionTimeoutMs); user.setSessionTimeoutMs(sessionTimeoutMs); user.setSessionTimeoutMs(sessionTimeoutMs); terminateSessions(user); } }
Expand All @@ -451,17 +455,22 @@ public void changeUser(@ApiParam(name = "userId", value = "The ID of the user to userManagementService.update(user, cr); }
private void updateExistingSession(User user, long newSessionTimeOut) { AllUserSessions allUserSessions = AllUserSessions.create(sessionService); allUserSessions.forUser(user).ifPresent(userSession -> { userSession.setTimeout(newSessionTimeOut); Session session = sessionService.daoToSimpleSession(userSession);
DefaultSecurityManager securityManager = (DefaultSecurityManager) SecurityUtils.getSecurityManager(); DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager(); SessionDAO sessionDAO = sessionManager.getSessionDAO(); sessionDAO.update(session); }); private void terminateSessions(User user) { final List<Session> allSessions = sessionTerminationService.getActiveSessionsForUser(user);
final Subject subject = getSubject(); final Session currentSession = subject.getSession(false); final User currentUser = getCurrentUser();
if (currentSession != null && currentUser != null && user.getId().equals(currentUser.getId())) { // Stop all sessions but handle the current session differently by issuing a proper logout allSessions.stream() .filter(session -> !session.getId().equals(currentSession.getId())) .forEach(Session::stop); securityManager.logout(subject); } else { allSessions.forEach(Session::stop); } }
private boolean rolesContainAdmin(List<String> roles) { Expand Down

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907