
Cloud Vulnerability DB
A community-led vulnerabilities database
CVE-2026-31069 is a SQL Injection vulnerability in BillaBear's EventRepository component, classified as CWE-89. It affects all versions of BillaBear up to and including 2025.01.03 (the latest GitHub release at time of disclosure). The vulnerability was discovered on January 13, 2026, reported to the vendor the same day, and publicly disclosed on April 13, 2026; the GitHub Advisory (GHSA-xp6r-8pcc-xv5p) was published May 19, 2026. It carries a CVSS v3.1 base score of 8.8 (High) (Github Advisory, Researcher Report).
The root cause (CWE-89) lies in src/BillaBear/Repository/Usage/EventRepository.php, where user-controlled metric filter names and aggregation properties are directly interpolated into raw SQL strings via PHP's sprintf() without sanitization or identifier quoting. While filter values are properly bound as parameterized query inputs, filter identifiers (keys/names) are concatenated directly into the SQL string across five methods: createCountSql(), createSumSql(), createMaxSql(), createLatestSql(), and createCountUnique(). The CreateMetricFilter DTO applies only NotBlank and Type('string') constraints on the name field — no regex or character restrictions — leaving the injection path fully open. This is a second-order (stored) SQL injection: the malicious payload is stored in the database when a metric is created via POST /app/metric, and executes later when any usage calculation is triggered (invoice generation, billing cycle processing, or usage report viewing) (Researcher Report, Researcher PoC).
Successful exploitation grants an authenticated attacker with ROLE_ACCOUNT_MANAGER permissions full read, write, and delete access to the underlying PostgreSQL database. This includes access to admin credentials (password hashes), all customers' payment data and PII, API keys, secrets, and system configuration — far exceeding the intended access boundary of the account manager role. In multi-tenant SaaS deployments, a malicious customer granted ROLE_ACCOUNT_MANAGER for their own organization could exfiltrate data belonging to other tenants, achieving complete tenant isolation bypass. Availability impact includes potential database destruction or denial-of-service via resource exhaustion, with regulatory implications under GDPR and PCI-DSS (Researcher Report, Github Advisory).
ROLE_ACCOUNT_MANAGER permissions.POST request to /app/metric with a filter name field containing a SQL injection payload. Example:curl -X POST "http://TARGET/app/metric" \
-H "Content-Type: application/json" \
-H "Cookie: PHPSESSID=<session>" \
-d '{
"name": "Malicious Metric",
"code": "malicious_test",
"aggregation_method": "count",
"filters": [{"name": "x''); SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END; --", "value": "anything", "type": "inclusive"}]
}'GET on usage reports endpoint), generating an invoice, or initiating a billing cycle for a subscription associated with the malicious metric.EventRepository methods (createCountSql(), createSumSql(), etc.) interpolate the stored filter name directly into the SQL query via sprintf(), executing the injected SQL against the PostgreSQL database."name": "x' UNION SELECT version()::text, NULL, NULL FROM pg_database LIMIT 1; --"POST requests to /app/metric or /app/metric/{id}/update with unusually long or syntactically complex name fields in filter objects containing SQL keywords (SELECT, UNION, pg_sleep, OR 1=1, --).POST /app/metric requests from ROLE_ACCOUNT_MANAGER accounts followed by delayed responses (indicative of time-based blind injection via pg_sleep); PostgreSQL query logs showing unexpected SQL constructs originating from the application's database user.', ;, --, UNION, SELECT); unexpected queries in PostgreSQL's pg_stat_activity or slow query logs referencing pg_sleep or UNION SELECT.The GitHub Advisory lists no patched version as of publication — affected versions include all releases up to and including 2025.01.03, and the advisory notes "Patched versions: None" (Github Advisory). Operators should upgrade to a BillaBear release published after January 2026 once available. As immediate workarounds: (1) apply whitelist regex validation (/^[a-zA-Z_][a-zA-Z0-9_]*$/) to the name field in CreateMetricFilter.php; (2) use $this->connection->quoteIdentifier() in EventRepository.php before interpolating filter names into SQL; or (3) use parameterized JSON path queries (PostgreSQL 12+). Additionally, restrict ROLE_ACCOUNT_MANAGER assignments to the minimum necessary users and monitor database access for anomalous query patterns (Researcher Report).
The vulnerability was discovered and disclosed by researcher nedlir, who published detailed technical write-ups and reproduction steps via GitHub Gists after receiving no vendor response following initial contact on January 13, 2026. The disclosure followed a responsible disclosure timeline with public release on April 13, 2026, approximately 90 days after discovery. No significant vendor statement, broader media coverage, or notable community discussion has been identified beyond the researcher's own publications (Researcher Report, Github Advisory).
Source: This report was generated using AI
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."