CVE-2026-44706: SQL Injection in Chatwoot FilterService lets any agent dump the PostgreSQL database
The Hakai Security Research Team disclosed CVE-2026-44706, a SQL Injection in Chatwoot versions <= 4.11.1. Any authenticated user with agent privileges, the lowest access level, can read the entire PostgreSQL database. The flaw sits in the FilterService, where user input is interpolated directly into SQL. Exposed data includes bcrypt password hashes, API access tokens that allow impersonation of any user including SuperAdmins, customer conversations and PII, and cross-account data in multi-tenant deployments. The researchers published a working PoC, and the article notes the flaw had already been disclosed by another researcher. The article does not report in-the-wild exploitation.
Detalhes técnicos
- Root cause: in
app/services/filter_service.rb, thelt_gt_filter_valuesmethod interpolatesvalues[0]directly into SQL for theis_greater_thanandis_less_thanoperators. All other operators use bind parameters. - A second sink: the
attribute_keyof a custom attribute was interpolated unparameterized into the JSON path expression inbuild_custom_attr_query. An attacker could create a custom attribute with a crafted key and trigger the injection on any filter call that referenced it. - Affected endpoints:
POST /api/v1/accounts/:id/conversations/filterandPOST /api/v1/accounts/:id/contacts/filter. - The payload escapes the string context using the date-cast pattern and enables time-based blind extraction via
pg_sleep()inside aCASE WHENexpression. Boolean-based inference also works. - DoS: concurrent requests with high
pg_sleep()values can exhaust the Rails connection pool and PostgreSQLmax_connections. Default deployments set nostatement_timeoutor rate limiting on the filter endpoints. - The PoC (
poc.py) hascheck,extractandcredsmodes, the last of which dumps emails, bcrypt hashes and API tokens. - Hunting guidance: inspect
custom_attribute_definitions.attribute_keyfor quotes, parentheses, whitespace or other SQL metacharacters, and review filter request payloads.
Remediação
- Upgrade to a patched Chatwoot release (> 4.11.1; the fix shipped in 4.11.2). It uses parameterized queries, type coercion (date/numeric) and strict
attribute_keyvalidation (/\A[\p{L}\p{N}_.\-]+\z/) withsanitize_sql_array. - Apply least privilege to the application's database account, avoiding SUPERUSER or CREATE privileges.
- Configure
statement_timeoutin PostgreSQL to limit DoS from long-running injected queries. - If a vulnerable version was running, assume compromise and rotate all user passwords and API tokens.
- Exposure of customer PII may trigger LGPD, GDPR or similar regulatory obligations.
Linha do tempo
-
CVE-2026-44706: SQL Injection in Chatwoot FilterService lets any agent dump the PostgreSQL database
ler a análise desta fonte ocultar
The Hakai Security Research Team disclosed CVE-2026-44706, a SQL Injection in Chatwoot versions <= 4.11.1. Any authenticated user with agent privileges, the lowest access level, can read the entire PostgreSQL database. The flaw sits in the
FilterService, where user input is interpolated directly into SQL. Exposed data includes bcrypt password hashes, API access tokens that allow impersonation of any user including SuperAdmins, customer conversations and PII, and cross-account data in multi-tenant deployments. The researchers published a working PoC, and the article notes the flaw had already been disclosed by another researcher. The article does not report in-the-wild exploitation.Technical Details
- Root cause: in
app/services/filter_service.rb, thelt_gt_filter_valuesmethod interpolatesvalues[0]directly into SQL for theis_greater_thanandis_less_thanoperators. All other operators use bind parameters. - A second sink: the
attribute_keyof a custom attribute was interpolated unparameterized into the JSON path expression inbuild_custom_attr_query. An attacker could create a custom attribute with a crafted key and trigger the injection on any filter call that referenced it. - Affected endpoints:
POST /api/v1/accounts/:id/conversations/filterandPOST /api/v1/accounts/:id/contacts/filter. - The payload escapes the string context using the date-cast pattern and enables time-based blind extraction via
pg_sleep()inside aCASE WHENexpression. Boolean-based inference also works. - DoS: concurrent requests with high
pg_sleep()values can exhaust the Rails connection pool and PostgreSQLmax_connections. Default deployments set nostatement_timeoutor rate limiting on the filter endpoints. - The PoC (
poc.py) hascheck,extractandcredsmodes, the last of which dumps emails, bcrypt hashes and API tokens. - Hunting guidance: inspect
custom_attribute_definitions.attribute_keyfor quotes, parentheses, whitespace or other SQL metacharacters, and review filter request payloads.
Remediation
- Upgrade to a patched Chatwoot release (> 4.11.1; the fix shipped in 4.11.2). It uses parameterized queries, type coercion (date/numeric) and strict
attribute_keyvalidation (/\A[\p{L}\p{N}_.\-]+\z/) withsanitize_sql_array. - Apply least privilege to the application's database account, avoiding SUPERUSER or CREATE privileges.
- Configure
statement_timeoutin PostgreSQL to limit DoS from long-running injected queries. - If a vulnerable version was running, assume compromise and rotate all user passwords and API tokens.
- Exposure of customer PII may trigger LGPD, GDPR or similar regulatory obligations.
- Root cause: in