flawopen.com/SQL Injection in Ruby/ActiveRecord where()
Is Rails where() string interpolation safe?
Think of SQL as a form with fixed instructions and empty value boxes. A bound parameter fills a box; Ruby interpolation writes request text into the instructions before Rails can separate the two. Keep SQL structure fixed and pass untrusted values as parameters.
User.where(
"id = #{params[:id]}"
)
User.where(id: params[:id])
# or, for more complex conditions:
User.where("id = ?", params[:id])
Why interpolation changes the query
Ruby evaluates #{...} before Active Record receives the condition. For example, where("id = #{params[:id]}") gives Rails an already-combined SQL string; request input may then change the predicate. Active Record documents this string-building pattern as unsafe. Use a hash for supported equality, range, or subset conditions, or use ? placeholders for other predicates. Placeholders bind values, not identifiers or SQL keywords; keep query structure fixed or choose identifiers from a strict allowlist.
How to check your codebase
rg -n 'where\s*\(' app/FAQ
No. Rails hash conditions support equality, range, and subset (IN) checks. For other predicates, use a fixed SQL condition with bound values, such as where("price > ?", amount). Binding protects values; it does not make dynamic table names, column names, or SQL fragments safe.