Fix N1QL injection in nested Hash attribute updates#33
Conversation
In build_update, Hash values were interpolated directly into the query string without sanitization, allowing N1QL injection. Use quote() to properly escape values. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request updates the Couchbase ORM relation builder to properly quote hash values when constructing update queries. The review feedback highlights a potential N1QL syntax error when a value is nil, as the quoted value would interpolate to an empty string, and suggests adding a fallback to 'NULL'.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
When a nil value is passed in a Hash update (e.g. update(field: { key: nil })),
quote() returns nil which interpolates as an empty string, producing invalid
N1QL syntax. Fall back to 'NULL' literal in that case.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| if value.is_a?(Hash) | ||
| value.map do |k, v| | ||
| "#{key}.#{k} = #{v}" | ||
| "#{key}.#{k} = #{@model.quote(v) || 'NULL'}" |
There was a problem hiding this comment.
A la place du || NULL, une meilleure approche serait de corriger quote elle-même pour retourner 'NULL' au lieu de nil — ce qui fixerait le problème à la source pour tous les appelants. Mais dans le cadre de cette PR (qui ne touche que le cas Hash), le fix local proposé par Gemini est raisonnable.
Cover string values, nil values, and special character quoting in Hash-style update_all to verify the N1QL injection fix. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
build_updatewhere nested Hash values (#{key}.#{k} = #{v}) were interpolated directly into the query string without sanitizationquote(v)to properly escape user-supplied valuesContext
In
Relation#build_update, when updating nested Hash attributes (e.g.update_all(address: { city: user_input })), the value was interpolated raw into the N1QL query string. This allowed N1QL injection through crafted values.Test plan
update_allspecs pass (nested attribute updates with_forclauses)/test --fail-fast=false🤖 Generated with Claude Code