fix(node-core): sql injection in dynamic datasource appending via unescaped json serialization#3031
Conversation
…ng via unescaped json serialization
The `APPEND_DS_QUERY` function constructs a raw SQL query by directly interpolating `JSON.stringify(item)` into a single-quoted SQL string literal (`'${JSON.stringify(item)}'::jsonb`). Because `JSON.stringify` does not escape single quotes, any single quote within the `item` payload (which represents dynamic datasource parameters, often derived from untrusted on-chain events) will break out of the SQL string literal. This allows an attacker to inject arbitrary SQL commands into the indexer's database by emitting crafted events on-chain.
Affected files: utils.ts
Signed-off-by: ChinhLee <[email protected]>
📝 WalkthroughWalkthroughFixed a SQL injection vulnerability in the Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/node-core/src/indexer/storeModelProvider/metadata/utils.ts (1)
28-28: Add a regression test for malicious quote-containing datasource payloads.Please add a focused test that passes
DatasourceParamsvalues likeO'Reillyand SQL-looking fragments, then asserts the generated SQL contains doubled quotes (e.g.'') and remains a valid::jsonbliteral.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/node-core/src/indexer/storeModelProvider/metadata/utils.ts` at line 28, Add a regression test that constructs DatasourceParams containing quote-bearing and SQL-looking values (e.g. "O'Reilly" and "'); DROP TABLE users;--") and passes them into the same SQL-generation helper in packages/node-core/src/indexer/storeModelProvider/metadata/utils.ts that produces the jsonb_set(...) expression (reference the template using VALUE and value/item interpolation shown in the diff). The test should assert the generated SQL literal doubles single quotes (e.g. O''Reilly), that the quoted fragment is still followed by ::jsonb, and that the overall string is a valid JSONB literal (you can assert presence of the doubled quotes and the trailing ::jsonb token and optionally try parsing/validating the JSON literal if a helper exists). Ensure the test covers both simple quote and SQL-like payloads.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/node-core/src/indexer/storeModelProvider/metadata/utils.ts`:
- Line 28: Add a regression test that constructs DatasourceParams containing
quote-bearing and SQL-looking values (e.g. "O'Reilly" and "'); DROP TABLE
users;--") and passes them into the same SQL-generation helper in
packages/node-core/src/indexer/storeModelProvider/metadata/utils.ts that
produces the jsonb_set(...) expression (reference the template using VALUE and
value/item interpolation shown in the diff). The test should assert the
generated SQL literal doubles single quotes (e.g. O''Reilly), that the quoted
fragment is still followed by ::jsonb, and that the overall string is a valid
JSONB literal (you can assert presence of the doubled quotes and the trailing
::jsonb token and optionally try parsing/validating the JSON literal if a helper
exists). Ensure the test covers both simple quote and SQL-like payloads.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b9ca93d4-ffd7-4d3b-abbe-360431b7fa43
📒 Files selected for processing (1)
packages/node-core/src/indexer/storeModelProvider/metadata/utils.ts
|
Thanks for contributing. |
🔒 Security Fix
Problem
The
APPEND_DS_QUERYfunction constructs a raw SQL query by directly interpolatingJSON.stringify(item)into a single-quoted SQL string literal ('${JSON.stringify(item)}'::jsonb). BecauseJSON.stringifydoes not escape single quotes, any single quote within theitempayload (which represents dynamic datasource parameters, often derived from untrusted on-chain events) will break out of the SQL string literal. This allows an attacker to inject arbitrary SQL commands into the indexer's database by emitting crafted events on-chain.Severity:
highFile:
packages/node-core/src/indexer/storeModelProvider/metadata/utils.tsSolution
Escape single quotes in the serialized JSON string by replacing them with double single quotes (
'') before interpolation:Changes
packages/node-core/src/indexer/storeModelProvider/metadata/utils.ts(modified)Description
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
Fixes # (issue)
Type of change
Please delete options that are not relevant.
Checklist
Contributed by Lê Thành Chỉnh
Code is a tool. Mindset is the real value.
Closes #3030
Summary by CodeRabbit