The datapoint export API builds a PostgreSQL crosstab export query by concatenating asset display names into raw SQL. An authenticated user who can create or rename an asset and then request a crosstab datapoint export can inject SQL through the asset name. The injected query output is streamed back to the caller inside the normal ZIP/CSV export response.
This creates a practical database exfiltration primitive through the application API. In a multi-tenant deployment, this can expose data outside the attacker's tenant if the application database role can read shared manager tables.
COPY (SELECT ... FROM crosstab(...)) TO STDOUT statement.Impact is high. A remote authenticated attacker with asset read/write capabilities can:
SELECT results in the exported CSV contained in the ZIP response.The demonstrated impact is database data exfiltration. The proof of concept safely retrieved database execution context and an aggregate table count. A real attacker could adapt the injected SELECT to read other database tables accessible to the application database role.
This is especially sensitive in multi-tenant deployments because application tables commonly contain data for multiple realms/tenants in the same database.
The attacker needs:
No direct database access is required. No server filesystem access is required. No token forgery is required.
The export implementation derives a crosstab header from the asset name and attribute name. It then embeds that header into two SQL contexts:
"<asset name> : <attribute name>" text
crosstab(...), wrapped in a fixed dollar-quoted delimiter:$cat$ SELECT header FROM (VALUES ('<asset name> : <attribute name>')) AS t(header) $cat$
The current escaping is incomplete:
As a result, an attacker-controlled asset name can break out of the intended SQL grammar boundary and append SQL to the generated COPY ... TO STDOUT query. Because the backend streams COPY output into the export response, injected query rows are returned to the attacker as CSV.
A safe proof query demonstrated exfiltration of:
current_usercurrent_database()count(*) from an application tableThe returned CSV contained a row equivalent to:
<timestamp>,<database_user>:<database_name>:<table_count>
The root cause is manual SQL string construction using user-controlled display data as SQL syntax.
The asset name is treated as presentation data in the application model, but later reused as part of executable SQL:
These contexts require different escaping rules. Applying partial string escaping is error-prone and currently misses exploitable grammar boundaries.
Avoid embedding user-controlled asset names directly into executable SQL.
Recommended options:
Do not use asset names as SQL identifiers.
c1, c2, c3.If dynamic identifiers are unavoidable, quote them using a database-aware identifier quoting function.
" characters.Avoid fixed dollar-quote delimiters around attacker-influenced content.
Add a strict validation boundary for display names if the product can tolerate it.
Add regression tests for:
".Build the crosstab with internal, non-user-controlled category keys and column names. For example:
col_0, col_1.col_0 to the display label.This removes asset display names from SQL syntax entirely.
Suggested severity: High
Rationale:
A vulnerability database tells you what is broken. Attack surface management tells you where it is running: it discovers your internet-facing assets and flags the ones affected by issues like this one.
What is attack surface management? →A security vulnerability is a weakness in software, hardware, or configuration that can be exploited to compromise confidentiality, integrity, or availability. Many vulnerabilities are tracked as CVEs (Common Vulnerabilities and Exposures), which provide a standardized identifier so teams can coordinate patching, mitigation, and risk assessment across tools and vendors.
CVSS (Common Vulnerability Scoring System) estimates technical severity, but it doesn't automatically equal business risk. Prioritize using context like internet exposure, affected asset criticality, known exploitation (proof-of-concept or in-the-wild), and whether compensating controls exist. A "Medium" CVSS on an exposed, production system can be more urgent than a "Critical" on an isolated, non-production host.
A vulnerability is the underlying weakness. An exploit is the method or code used to take advantage of it. A zero-day is a vulnerability that is unknown to the vendor or has no publicly available fix when attackers begin using it. In practice, risk increases sharply when exploitation becomes reliable or widespread.
Recurring findings usually come from incomplete Asset Discovery, inconsistent patch management, inherited images, and configuration drift. In modern environments, you also need to watch the software supply chain: dependencies, containers, build pipelines, and third-party services can reintroduce the same weakness even after you patch a single host. Unknown or unmanaged assets (often called Shadow IT) are a common reason the same issues resurface.
Use a simple, repeatable triage model: focus first on externally exposed assets, high-value systems (identity, VPN, email, production), vulnerabilities with known exploits, and issues that enable remote code execution or privilege escalation. Then enforce patch SLAs and track progress using consistent metrics so remediation is steady, not reactive.
SynScan combines attack surface monitoring and continuous security auditing to keep your inventory current, flag high-impact vulnerabilities early, and help you turn raw findings into a practical remediation plan.