CVE-2026-62238: OpenRemote has Authenticated SQL Injection via Datapoint Crosstab Export

Published Jul 6, 2026
·
Updated

Summary

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.

Affected Component

- Datapoint export endpoint for asset datapoints. - Crosstab export formats, specifically CSV crosstab-style exports. - Query builder path that constructs a COPY (SELECT ... FROM crosstab(...)) TO STDOUT statement.

Security Impact

Impact is high. A remote authenticated attacker with asset read/write capabilities can:

- Store SQL syntax inside an asset name. - Trigger the crosstab export path for that asset. - Cause the backend to execute attacker-influenced SQL through the PostgreSQL connection used by the manager service. - Receive injected 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.

Attack Preconditions

The attacker needs:

- A valid authenticated session. - Permission to create or rename at least one asset. - Permission to read/export datapoints for at least one attribute on that asset. - Access to a crosstab datapoint export format.

No direct database access is required. No server filesystem access is required. No token forgery is required.

Technical Details

The export implementation derives a crosstab header from the asset name and attribute name. It then embeds that header into two SQL contexts:

1. A PostgreSQL double-quoted column identifier:

sql "<asset name> : <attribute name>" text

2. A category query passed to crosstab(...), wrapped in a fixed dollar-quoted delimiter:

sql $cat$ SELECT header FROM (VALUES ('<asset name> : <attribute name>')) AS t(header) $cat$

The current escaping is incomplete:

- Single quotes are escaped in one string-literal context. - Double quotes in asset names are not escaped before being placed inside quoted identifiers. - The fixed dollar-quote delimiter is not protected against an asset name containing the delimiter token.

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.

Example Exploit Flow

1. Authenticate normally. 2. Create or rename an asset using a name containing SQL metacharacters that closes the crosstab column definition. 3. Ensure the asset has an exportable datapoint attribute. 4. Write at least one datapoint value for that attribute, if necessary. 5. Request a CSV crosstab datapoint export for the crafted asset attribute. 6. Inspect the returned ZIP/CSV. The CSV contains both normal datapoint rows and rows produced by the injected SQL.

A safe proof query demonstrated exfiltration of:

- currentuser - currentdatabase() - count() from an application table

The returned CSV contained a row equivalent to:

text <timestamp>,<databaseuser>:<databasename>:<tablecount>

Root Cause

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:

- As an SQL identifier in the crosstab output column list. - As a value inside a category query string passed to PostgreSQL.

These contexts require different escaping rules. Applying partial string escaping is error-prone and currently misses exploitable grammar boundaries.

Recommended Fix

Avoid embedding user-controlled asset names directly into executable SQL.

Recommended options:

1. Do not use asset names as SQL identifiers. - Generate deterministic internal column aliases such as c1, c2, c3. - Keep the user-facing asset/attribute labels outside SQL and apply them only when serializing CSV headers.

2. If dynamic identifiers are unavoidable, quote them using a database-aware identifier quoting function. - For PostgreSQL identifiers, double embedded " characters. - Do not perform ad hoc quoting with string concatenation.

3. Avoid fixed dollar-quote delimiters around attacker-influenced content. - Use prepared statements or server-side functions where possible. - If textual SQL must be generated, choose a delimiter that cannot appear in user input or escape/validate before use.

4. Add a strict validation boundary for display names if the product can tolerate it. - This should be defense-in-depth, not the only fix. - Reject control characters and SQL-significant delimiter sequences in asset names if they are not required.

5. Add regression tests for: - Asset names containing ". - Asset names containing the fixed dollar-quote delimiter. - Asset names containing newline/comment syntax. - Crosstab exports with multiple assets and attributes. - Confirmation that returned CSV never contains injected query output.

Suggested Safe Design

Build the crosstab with internal, non-user-controlled category keys and column names. For example:

- Use asset IDs and attribute names only as parameterized data for filtering. - Generate internal column identifiers such as col0, col1. - Maintain a separate mapping from col0 to the display label. - Replace the CSV header row after query execution using application-side serialization, not SQL identifiers derived from user input.

This removes asset display names from SQL syntax entirely.

Severity

Suggested severity: High

Rationale:

- Network reachable through the authenticated API. - Low attack complexity after authentication. - Requires only ordinary asset read/write/export capabilities. - Demonstrated SQL injection result exfiltration through a normal application response. - High confidentiality impact due to possible cross-tenant database reads. - Integrity and availability impact were not required for the demonstrated exploit and should be assessed separately based on the database role's privileges.

Other sources

OpenRemote before 1.26.0 contain an authenticated SQL injection vulnerability in the datapoint crosstab export endpoint that constructs PostgreSQL queries by concatenating asset display names into raw SQL. An authenticated attacker with asset creation or rename permissions can inject SQL through the asset name parameter and receive query results in the exported CSV response, enabling database data exfiltration.

— MITRE

OpenRemote is an open-source internet-of-things platform. Prior to 1.26.0, the datapoint export API constructs CSV crosstab SQL by concatenating an asset name and attribute name into a COPY query that uses crosstab and streams TO STDOUT. The asset name enters both a double-quoted column identifier and a category query enclosed by the fixed $cat$ delimiter. Escaping single quotes in one string context does not escape embedded double quotes in identifiers or protect that dollar-quote boundary. An authenticated user permitted to create or rename an asset and read/export datapoints for one of its attributes can store SQL metacharacters in the name and request a crosstab export, causing injected SELECT output to be returned in the normal ZIP/CSV response. This enables database exfiltration without direct database or filesystem access or token forgery. In a multi-tenant deployment it can expose other tenants' data if the manager's database role can read shared tables; integrity and availability effects are not established by the demonstrated read primitive. This issue is fixed in version 1.26.0.

— OSV

Affected Software

3 affected componentsFixes available
OpenRemote OpenRemote<1.26.0
OpenRemote OpenRemote<1.26.0
maven/io.openremote:openremote-manager<1.26.0
1.26.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade maven/io.openremote:openremote-manager to a version that resolves this vulnerability.

    Fixed in 1.26.0
  2. Upgrade

    Upgrade OpenRemote to a version that resolves this vulnerability.

    Fixed in 1.26.0
  3. Compensating control

    Build crosstab exports with internal non-user-controlled column identifiers such as col_0, col_1 or c1, c2, c3; keep asset and attribute display labels outside SQL and apply them when serializing CSV headers. Use asset IDs and attribute names as parameterized data for filtering, and use database-aware identifier quoting or prepared statements where dynamic SQL is unavoidable.

Event History

Jul 6, 2026
Advisory Published
via OSV·09:51 PM
Data Sourced
via OSV·09:51 PM
DescriptionSeverityWeaknessAffected Software
Jul 17, 2026
CVE Published
via MITRE·12:07 AM
Data Sourced
via MITRE·12:07 AM
DescriptionWeakness
Data Sourced
via NVD·02:18 AM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

What is the severity of CVE-2026-62238?

CVE-2026-62238 has a high severity rating of 7.2 according to the CVSS scoring system.

2

How do I fix CVE-2026-62238?

To fix CVE-2026-62238, upgrade OpenRemote to version 1.26.0 or later, where the vulnerability is patched.

3

What type of vulnerability is CVE-2026-62238?

CVE-2026-62238 is classified as an SQL Injection vulnerability.

4

Who can exploit CVE-2026-62238?

An authenticated attacker with asset creation or rename permissions can exploit CVE-2026-62238 to inject SQL.

5

What component of OpenRemote is affected by CVE-2026-62238?

CVE-2026-62238 affects the datapoint crosstab export endpoint in OpenRemote versions before 1.26.0.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203