EspoCRM: Blind SQL Injection via streamAttachments where-Clause

EspoCRM's streamAttachments endpoint improperly validates complex expressions in the where parameter, letting a low-privileged authenticated user trigger a blind SQL injection, extract sensitive data such as active admin session tokens, and escalate privileges.

Advisory ID: TP-2026-032
Product: EspoCRM (open-source CRM, self-hosted)
Vulnerability type: Blind SQL injection via complex expression in the where parameter (CWE-89)
CVE: CVE-2026-53574
CVSS 3.1: 7.6 (High) · CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L
Affected versions: >= 8.1.0, <= 9.3.7
Fixed in: 9.3.8
Vendor advisory: GHSA-qgm7-fc9g-fj75
Reported: 31 May 2026

Summary

EspoCRM is a widely used open-source CRM. The GET /api/v1/<Entity>/<id>/streamAttachments endpoint does not properly validate complex expressions in the where parameter. Unlike other query paths, this endpoint does not prohibit such expressions, so a low-privileged authenticated user can trigger a blind SQL injection through the where parameter. Using a boolean- or time-based oracle, an attacker can read arbitrary database contents, including active administrator session tokens, enabling privilege escalation up to admin account takeover. turingpoint verified and reported the issue; the vendor fixed it in 9.3.8.

Root cause

EspoCRM's where checker permits complex expressions (attributes prefixed with #) on the streamAttachments path without prohibiting them. The expression flows into the ORM query and is not sufficiently escaped when the SQL statement is built, so attacker-controlled SQL fragments reach the WHERE clause. The fix adds an additional check in the where checker that rejects complex expressions on this path.

Proof of Concept

# Schematic. Authenticated as a regular low-privileged user.
# The streamAttachments where parameter accepts complex expressions
# (attributes prefixed with "#") that are not validated and reach the
# SQL query unescaped.

GET /api/v1/Account/<recordId>/streamAttachments
    ?where[0][type]=equals
    &where[0][attribute]=%23<injected SQL expression>
    &where[0][value]=1
Header: Espo-Authorization: <base64(user:token)>

# The "#"-prefixed attribute is emitted into the WHERE clause unescaped
# and enables a blind boolean/time-based oracle:
#   ... WHERE (<injected SQL expression>) = '1'
# Iterating the oracle extracts arbitrary column values, e.g. an active
# administrator's auth_token, which is then replayed to take over the
# admin account.

Impact

  • Blind read of arbitrary database contents via a boolean/time-based oracle.
  • Extraction of active administrator session tokens, enabling privilege escalation up to admin account takeover.
  • Access to sensitive CRM data beyond the attacker's own permission scope.
  • Requires only a low-privileged authenticated account, no admin rights and no user interaction.

References

Is Something Like This in Your Software?

Our team found this vulnerability in the course of its work. Have your applications tested by the same specialists, with a penetration test from turingpoint.