I was developing a specific filter when I ran into the following question:
input_from_user = Arel::Nodes::Quoted.new(input_from_user.split('.').second)
separator = Arel::Nodes::Quoted.new('.')
Model.where(Arel::Nodes::NamedFunction.new('split_part', [input_from_user, separator, 2]).eq('random_value'))
This works, but I am not sure if this is really secure, I know that 'Arel.sql' or 'Literal' would not garantee any security, 'Quoted' node seems to handle injection, but I am not 100% into injection security, is there any other way to write this? (which does not involves creating fields on the database) if not, is this safe?
TL;DR:
Yes these will be escaped accordingly, just as they would be for higher level AR query methods.
Explanation:
So here is how Nodes::NamedFunction
will work in SQL compilation (in a nut shell):
Nodes::NamedFunction
(Source)Nodes::Quoted
visit those expressions (Source)quote
method (Source)quote
method (Source)quote
method because these are String
s (Source)quote_string
to escape strings (Source)escape
method (from the pg
gem) (Source or Docs because they are easier to read)The result will be split_part('input_from_user','.',2)
.
Additional Notes:
where
does not have an queryable expression (no predication) of any kind so you would need to modify this to something like the following (which will generate an Arel::Nodes::Equality
object)Model.where(
Arel::Nodes::NamedFunction.new(
'split_part',
[input_from_user, separator, 2]
).eq('sub string'))
Arel::Nodes
provides a convenience method (build_quoted
) that reads a little nicer. e.g.input_from_user = Arel::Nodes.build_quoted(input_from_user.split('.').second)
separator = Arel::Nodes.build_quoted('.')
Model.where(
Arel::Nodes::NamedFunction.new(
'split_part',
[input_from_user, separator, 2]
).eq('sub string'))