Skip to content

fix(sec): sql injection in validate jsonpath query (CVE-2026-8462)#4383

Merged
chrisgacsal merged 1 commit into
mainfrom
fix/sql-injection
May 19, 2026
Merged

fix(sec): sql injection in validate jsonpath query (CVE-2026-8462)#4383
chrisgacsal merged 1 commit into
mainfrom
fix/sql-injection

Conversation

@chrisgacsal
Copy link
Copy Markdown
Collaborator

@chrisgacsal chrisgacsal commented May 19, 2026

SQL Injection in ClickHouse-backed Meter Definitions (CVE-2026-8462)

An attacker may be able to perform SQL injection through meter configuration fields in POST /api/v1/meters when OpenMeter is configured to use ClickHouse as the event database.

The issue affects user-controlled JSONPath values which may be incorporated into ClickHouse queries without sufficient parameterization. Under vulnerable configurations, an attacker with access to the meter creation endpoint could craft a meter definition that alters the intended SQL query.

In multi-tenant ClickHouse deployments where tenant event data is stored in shared tables without database-enforced row-level isolation, successful exploitation could allow an attacker to access metering event data belonging to other tenants. Depending on the ClickHouse user's database permissions, additional impact such as data modification or denial of service through expensive queries may also be possible.

Am I affected?

You are affected if all of the following hold:

  1. You expose POST /api/v1/meters to untrusted users or without authentication.
  2. The meter creation endpoint can be reached without authentication or effective authorization.
  3. Meter definitions accept user-controlled values.

Resolution

Please upgrade to version v1.0.0-beta.228 or newer.

CVSS

CVSS v4.0: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P
Severity: High
Score: 8.9

Details

Please see the following security advisory: GHSA-wc3v-3457-c8cm

Summary by CodeRabbit

  • Tests

    • Added unit test coverage for ClickHouse JSON-path query handling to ensure consistent SQL output and parameters.
  • Refactor

    • Updated ClickHouse SQL generation to use parameterized building for safer, more consistent query construction and improved maintainability.

Review Change Stack

@chrisgacsal chrisgacsal requested a review from a team as a code owner May 19, 2026 13:45
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: af9228b9-a38d-4ac3-b735-d800480b625e

📥 Commits

Reviewing files that changed from the base of the PR and between 7e4e6e8 and be944a5.

📒 Files selected for processing (2)
  • openmeter/streaming/clickhouse/utils_query.go
  • openmeter/streaming/clickhouse/utils_query_test.go
✅ Files skipped from review due to trivial changes (1)
  • openmeter/streaming/clickhouse/utils_query_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • openmeter/streaming/clickhouse/utils_query.go

📝 Walkthrough

Walkthrough

This PR refactors how ClickHouse JSON path validation queries are generated. The implementation switches from manually constructed SQL with escaped strings to a parameterized query approach using sqlbuilder.Buildf with ClickHouse SQL flavor. A new unit test validates that the refactored method produces the expected SQL string and argument list.

Changes

JSON Path Query Parameterization

Layer / File(s) Summary
SQL generation refactor and test
openmeter/streaming/clickhouse/utils_query.go, openmeter/streaming/clickhouse/utils_query_test.go
validateJsonPathQuery.toSQL() switches from manual fmt.Sprintf and sqlbuilder.Escape to sqlbuilder.Buildf with parameterized JSON path injection and ClickHouse SQL flavor application. Test verifies output of SELECT JSON_VALUE('{}', ?) with JSONPath argument.

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: fixing a SQL injection vulnerability in the validateJsonPathQuery function, with the CVE identifier. The code changes show exactly this fix—refactoring from unsafe string concatenation to parameterized SQL using sqlbuilder.Buildf.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/sql-injection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chrisgacsal chrisgacsal self-assigned this May 19, 2026
@chrisgacsal chrisgacsal added the release-note/bug-fix Release note: Bug Fixes label May 19, 2026
tothandras
tothandras previously approved these changes May 19, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
openmeter/streaming/clickhouse/utils_query_test.go (1)

9-17: ⚡ Quick win

Add an injection-payload regression test for this CVE fix.

Nice baseline test. I’d also add one malicious JSONPath case to ensure payload content is always kept in args and never interpolated into SQL text.

Suggested test
 func Test_ValidateJsonPathQuery(t *testing.T) {
 	query, args := validateJsonPathQuery{
 		jsonPath: "$.foo.bar",
 	}.toSQL()

 	assert.Equal(t, `SELECT JSON_VALUE('{}', ?)`, query)
 	assert.Equal(t, []interface{}{
 		"$.foo.bar"}, args)
 }
+
+func Test_ValidateJsonPathQuery_InjectionPayloadIsParameterized(t *testing.T) {
+	payload := "$.foo.bar') OR 1=1 --"
+
+	query, args := validateJsonPathQuery{
+		jsonPath: payload,
+	}.toSQL()
+
+	assert.Equal(t, `SELECT JSON_VALUE('{}', ?)`, query)
+	assert.Equal(t, []interface{}{payload}, args)
+}

As per coding guidelines: "**/*_test.go: Make sure the tests are comprehensive and cover the changes. Keep a strong focus on unit tests and in-code integration tests."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@openmeter/streaming/clickhouse/utils_query_test.go` around lines 9 - 17,
Extend Test_ValidateJsonPathQuery by adding a regression case that passes a
malicious JSONPath (e.g. containing quotes, SQL keywords, semicolon or a payload
like "$.foo'); DROP TABLE users; --") into validateJsonPathQuery{jsonPath:
"..."} and assert the returned SQL string still uses a parameter placeholder
(e.g. contains "JSON_VALUE('{}', ?)") and that the args slice contains the exact
malicious JSONPath as a single element (no interpolation into the query); update
the test around the existing Test_ValidateJsonPathQuery function and the toSQL
invocation to verify query stays parameterized and args preserves the payload.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@openmeter/streaming/clickhouse/utils_query_test.go`:
- Around line 9-17: Extend Test_ValidateJsonPathQuery by adding a regression
case that passes a malicious JSONPath (e.g. containing quotes, SQL keywords,
semicolon or a payload like "$.foo'); DROP TABLE users; --") into
validateJsonPathQuery{jsonPath: "..."} and assert the returned SQL string still
uses a parameter placeholder (e.g. contains "JSON_VALUE('{}', ?)") and that the
args slice contains the exact malicious JSONPath as a single element (no
interpolation into the query); update the test around the existing
Test_ValidateJsonPathQuery function and the toSQL invocation to verify query
stays parameterized and args preserves the payload.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c55294b4-6ff1-4603-ae28-34e12870899b

📥 Commits

Reviewing files that changed from the base of the PR and between c1f566c and 7e4e6e8.

📒 Files selected for processing (2)
  • openmeter/streaming/clickhouse/utils_query.go
  • openmeter/streaming/clickhouse/utils_query_test.go

turip
turip previously approved these changes May 19, 2026
borosr
borosr previously approved these changes May 19, 2026
@chrisgacsal chrisgacsal merged commit 6ce29e7 into main May 19, 2026
36 of 50 checks passed
@chrisgacsal chrisgacsal deleted the fix/sql-injection branch May 19, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants