Skip to content

Users can login with any password via the EE ddp-streamer-service

Critical
julio-rocketchat published GHSA-w6vw-mrgv-69vf Mar 5, 2026

Package

No package listed

Affected versions

< 8.0.0, < 7.13.3, < 7.12.4, < 7.11.4, < 7.10.7, < 7.9.8, < 7.8.6

Patched versions

8.0.0, 7.13.3, 7.12.4, 7.11.4, 7.10.7, 7.9.8, 7.8.6

Description

Issue 1: Users can login with any password via the EE ddp-streamer-service GHSL-2026-004)

A critical authentication bypass vulnerability exists in Rocket.Chat's account service used in the ddp-streamer micro service that allows an attacker to log in to the service as any user with a password set, using any arbitrary password. The vulnerability stems from a missing await keyword when calling an asynchronous password validation function, causing a Promise object (which is always truthy) to be evaluated instead of the actual boolean validation result. This may lead to account takeover of any user whose username is known or guessable.

The vulnerability originates from improper handling of asynchronous password validation in the authentication flow:

  1. Password Validation Function - ee/apps/account-service/src/lib/utils.ts

    The validatePassword function returns a Promise<boolean> by calling bcrypt.compare():

    export const validatePassword = (password: string, bcryptPassword: string): Promise<boolean> =>
        bcrypt.compare(getPassword(password), bcryptPassword);
  2. Missing Await in Login Logic - ee/apps/account-service/src/lib/loginViaUsername.ts

    The critical flaw occurs when validatePassword is called without await:

    const valid = user.services?.password?.bcrypt && validatePassword(password, user.services.password.bcrypt);
    
    if (!valid) {
        return false;
    }

Since a Promise object is always truthy in JavaScript, the condition !valid is never true when a bcrypt hash exists, bypassing password validation entirely.

The vulnerability is externally reachable through the login method exposed by the ddp-streamer micro service (reachable via <rocketchat-host>/websocket):

   server.methods({
       async login(resume, user, password) {
           const result = await Account.login({ resume, user, password });
           // ...
       }
   });

Impact

This issue leads to attackers being able to interact with available DDP methods, which may lead to account takeover depending on the attack path.

Remediation

Add the missing await to the validatePassword call.
Enable strict TypeScript compiler options to catch unawaited promises (@typescript-eslint/no-floating-promises)

CWEs

  • CWE-287: Improper Authentication

Credit

These issues were discovered by an AI agent developed by the GitHub Security Lab and reviewed by GHSL team members @p- (Peter Stöckli) and @m-y-mo (Man Yue Mo).

Contact

You can contact the GHSL team at [email protected], please include a reference to GHSL-2026-004 or GHSL-2026-005 in any communication regarding these issues.

Disclosure Policy

This report is subject to a 90-day disclosure deadline, as described in more detail in our coordinated disclosure policy.

Severity

Critical

CVE ID

CVE-2026-28514

Weaknesses

Improper Authentication

When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct. Learn more on MITRE.

Credits