Skip to main content
Vulnerability Database/CVE-2026-92298

CVE-2026-92298: EspoCRM Authentication Bypass Vulnerability

CVE-2026-92298 is an authentication bypass flaw in EspoCRM through version 10.0.8 that uses weak token generation. Attackers can guess tokens to hijack opt-ins and event invitations. This article covers technical details, affected versions, impact, and mitigation steps.

Published:

CVE-2026-92298 Overview

CVE-2026-92298 affects EspoCRM through version 10.0.8. The application uses PHP's rand() function to generate tokens for lead-capture opt-in, event invitation, and campaign URLs. Because rand() is not a cryptographically secure random number generator, the resulting tokens carry only about 31 bits of entropy. Remote unauthenticated attackers can guess these tokens to confirm opt-ins, accept or decline event invitations on behalf of other contacts, and access event details. The weakness maps to CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator.

Critical Impact

Unauthenticated attackers can guess predictable tokens to manipulate event invitations, confirm opt-ins, and disclose event data belonging to other EspoCRM contacts.

Affected Products

  • EspoCRM versions up to and including 10.0.8
  • EspoCRM lead-capture opt-in workflow
  • EspoCRM event invitation and campaign URL handlers

Discovery Timeline

  • 2026-09-16 - CVE-2026-92298 published to NVD
  • 2026-09-17 - Last updated in NVD database

Technical Details for CVE-2026-92298

Vulnerability Analysis

EspoCRM generates unique identifiers used in externally-facing URLs through the generateMoreEntropyId() helper in application/Espo/Core/Utils/Util.php. The helper concatenates truncated MD5 hashes seeded with the output of PHP's rand() and uniqid(). Both rand() and uniqid() are documented as non-cryptographic sources, and rand() on most platforms yields values in a 31-bit range.

The UniqueId repository at application/Espo/Repositories/UniqueId.php used this helper to mint tokens embedded in opt-in confirmation, event invitation, and campaign URLs. An attacker who can enumerate roughly 2^31 candidates against the public endpoints can locate valid tokens and perform actions attributed to the underlying contact.

Root Cause

The root cause is the use of a statistical pseudo-random number generator to produce security-sensitive tokens. rand() is not seeded from a cryptographically strong entropy source, and combining it with uniqid() and md5() does not restore the missing entropy. The generated token space is small enough for online enumeration against the affected EspoCRM endpoints.

Attack Vector

Exploitation is network-based and requires no authentication or user interaction. An attacker enumerates candidate token values against the opt-in, invitation, or campaign URL handlers. On a hit, the attacker can confirm a lead opt-in, accept or decline an event invitation for another contact, or view event details intended for the targeted invitee.

php
// Source: https://github.com/espocrm/espocrm/commit/8e5555c1ee0ed1e92a9ad54e62f735ac2c4051a1
// Vulnerable helper (pre-patch) and its replacement in Util.php.
// The pre-patch version relied on rand() and uniqid(), which are not cryptographically secure.

    /**
     * Generate an ID with more entropy.
     * @deprecated As of v10.1.0.
     * @todo Remove in v11.0.
     */
    public static function generateMoreEntropyId(): string
    {
        return self::generateCryptId();
    }

    /**
     * Generate a crypt ID.
     */
    public static function generateCryptId(): string
    {
        // Uses a cryptographically secure generator.
    }

The patch redirects generateMoreEntropyId() to generateCryptId(), and UniqueId::getNew() now calls Util::generateCryptId() directly. See the EspoCRM commit 8e5555c and the VulnCheck advisory for full technical context. A proof-of-concept is available as a GitHub Gist PoC.

Detect Identity Attacks the Moment Authentication Fails

Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.

Stop Identity Attacks

Detection Methods for CVE-2026-92298

Indicators of Compromise

  • High-volume requests to EspoCRM opt-in, invitation, or campaign URL paths with sequential or randomly varying token parameters from a single source.
  • Repeated HTTP 404 or invalid-token responses from the EspoCRM front-end followed by a successful 200 on a token that was never emailed to a contact.
  • Unexpected changes to lead opt-in status, event invitation responses (accept/decline), or event-detail views without matching outbound email delivery logs.

Detection Strategies

  • Baseline normal traffic to public EspoCRM endpoints that consume UniqueId tokens and alert on token-parameter entropy anomalies or brute-force rates.
  • Correlate web server access logs with EspoCRM application logs to identify token acceptances that lack a preceding legitimate email delivery event.
  • Search source repositories and running instances for use of Util::generateMoreEntropyId() prior to the fix in commit 8e5555c.

Monitoring Recommendations

  • Rate-limit and log all requests to opt-in confirmation, invitation response, and campaign tracking URLs.
  • Alert on any single client IP or ASN generating a large number of unique token guesses within short time windows.
  • Review audit trails for lead-capture and event-invitation state changes and reconcile them against expected recipient activity.

How to Mitigate CVE-2026-92298

Immediate Actions Required

  • Upgrade EspoCRM to a version that includes commit 8e5555c, which replaces generateMoreEntropyId() usage with generateCryptId().
  • Invalidate outstanding opt-in, invitation, and campaign tokens generated by the vulnerable code path and reissue them after upgrade.
  • Place a web application firewall or reverse proxy rule in front of the affected endpoints to rate-limit token enumeration.

Patch Information

The fix is published in the EspoCRM repository as commit 8e5555c. The patch modifies application/Espo/Core/Utils/Util.php and application/Espo/Repositories/UniqueId.php so that unique IDs are produced by Util::generateCryptId(), which relies on a cryptographically secure generator. Refer to the VulnCheck advisory for vendor guidance and to the EspoCRM GitHub repository for release notes.

Workarounds

  • Restrict access to opt-in, invitation, and campaign endpoints with strict per-IP rate limits and CAPTCHA challenges until patching is complete.
  • Shorten the validity window for tokens issued by the vulnerable code path and require re-authentication for state changes where feasible.
  • Monitor and alert on anomalous request rates to any URL that carries an UniqueId token.
bash
# Example nginx rate-limit for EspoCRM token-bearing endpoints
http {
    limit_req_zone $binary_remote_addr zone=espo_tokens:10m rate=10r/m;

    server {
        location ~ ^/(optin|event|campaign)/ {
            limit_req zone=espo_tokens burst=5 nodelay;
            proxy_pass http://espocrm_backend;
        }
    }
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.