Ensure my SQL is not injected receiving array of values - ruby-on-rails

I need to receive an array of values of like:
['restaurant']
['restaurant', 'pharmacy']
I would like which approach to take to ensure that when I use this:
SELECT * FROM places WHERE type IN (array_joined_with_commas_and_quotes)
I don't get injection attacks.
I am writing the sentence without any library and I am working in Rails.
I don't have Active Record, I am doing a postgis query to an external server.

How about using the ActiveRecord functions for query building?
If you use rails, the gem should still be there.
Place.where(:type => ['foo', 'bar']).to_sql

You have two basic approaches (using ? for parameterization in these examples).
If this is an array, then your ['restaurant', 'pharmacy'] becomes '{"restaurant","pharmacy"}' and then you can:
SELECT * FROM places WHERE type = ANY (?);
You could also
SELECT * FROM places WHERE type IN (? ....);
Dynamically generating the number of parameters as you go. As scones mentioned ActiveRecord may be able to automate this for you. The point though is that these methods send data separately from the query, which means that the SQL cannot be injected into the query.

Related

Rails Brakeman SQL injection warning while accessing an oracle view/function

I have rails code that is consuming an oracle view/function.
This is my code:
def run_query
connection.exec_query(
"SELECT * FROM TABLE(FN_REQ(#{demo_type_param},#{demo_tid_param}}))")
end
When run Brakeman analyzer it warns of possible "sql injection attack"
I need to understand if this is a valid warning, if so, how do I remediate it?
Since this is a function & not an actual table, I am not sure what's the right way.
If it was a normal model, i would have just followed this pattern:
Model.where("mycolumn1= ? AND mycolumn2= ?", demo_type_param, demo_tid_param).first
Yes, it is real. Almost every time, you build any SQL query from simply concatenating variables, you are vulnerable to SQL injection. Generally, an SQL injection happens each time when data inserted into the query can look like valid SQL and can result in additional queries executed.
The only solution is to manually enforce appropriate escaping or to use prepared statements, with the latter being the preferred solution.
With ActiveRecord / Rails, you can use exec_query with binds directly
sql = 'SELECT * FROM TABLE(FN_REQ(?,?))'
connection.exec_query(sql, 'my query', [demo_type_param, demo_tid_param])
Here, Rails will prepare the statement on the database and add the parameters to it on execution, ensuring that everything is correctly escaped and save from SQL injection.

Is ActiveRecord's “order” method passed with hash vulnerable to SQL injection?

Adding to the same question from (HERE), I am planning to use hash instead of string as parameter. Say,
User.order(params[:column].to_sym => params[:direction].to_sym)
Where params[:column] and params[:direction] are passed from the page for sorting the table (Reference). I even added .to_sym to both parameters just so that it will be forced into a symbol instead of string just to be safe (although I am not sure if this is even necessary)
Now, I would just like to know if this approach is safe.
P.S. tried ransack gem, however I couldn't do nested queries. So I wrote my own customizable one.
I think this is at least still open for a Denail of Service attack.
http://brakemanscanner.org/docs/warning_types/denial_of_service/index.html
The reference is from a nice gem called brakeman which finds vunerable things in a rails application.
In general I would advise you to use #dmcnally's approach from the other issue you posted.
Here an example of what I did in my own projects:
SORT = { newest: { created_at: :desc },
cheapest: { price: :asc },
most_expensive: { price: :desc }
}.stringify_keys
And then use SORT[param[:sort]] to get the sort order. You can also do this by using two seperate hashes for direction and column like you supposed. If you use brakeman you will be able to have a little but of safety since it finds most things like that.
Symbols don't protect you from SQL injection, query parametrization protects you from SQL injection - and this only on the value side, not on the column name side. The thing to take from the other article is "not safe to use interpolated strings in column name when calling .order", not "not safe to use strings when calling .order",
your example defines ordering using a hash - that hash gets translated into a parametrized SQL query in AR, so it is safe as long as you sanitize the column name. One liberal way to do this is to:
raise "Unknown column name #{params[:column]}" unless YourModel.column_names.include?(params[:column])
PS What .to_sym does in your example is that it enables a third party to define a new symbol on the ruby vm. Symbols are never garbage collected so the attacker can send many different values so that your ruby processes hog the system memory - thus opening you to a ddos attack. The cast in the end does nothing because if you look here you'll notice your value gets cast into string anyway :)

Prepared statements in ruby/rails with postgres

I want to execute a rather nasty recursive update query in rails. This means I want to write some raw postgres sql, with parameters, and execute it inside a rails controller.
How do I do that? I can't find a PreparedStatement class in activerecord, there don't seem to be any methods named 'native', I have tried ActiveRecord::Base.connection.exec_delete, I have looked through the source - just cannot, cannot work it out.
I've looked everywhere - the documentation goes in circles.
How would I tell postgres to execute
delete from foo where foo.bar=?
bind 'baz' to the q-mark, and do it without using the active record objects, finders, you-beaut subset thingies and all the rest.
I just want to execute a prepared statement with some bindings. How hard can it be?
(PS, and no: I don't want to jam the parameters into the string myself and execute it as unparameterised sql. It's wrong and it means I have to worry about sanitising the data.)
See the discussion of PreparedStatements in Rails ('Using Prepared Statements') here - http://blog.daniel-azuma.com/archives/216 . Shows you which methods to call, and how to format your arguments.
UPDATE:
Paraphrased from the post:
For the delete method arguments use the template first, followed by a query name (which can be nil) and then an array of values to inject into the statement. So like this:
row_count = connection.delete("DELETE FROM foo WHERE foo.bar=$1", nil, [[nil, 'baz']])

Ruby on Rails build query in pieces

There was a very similar question before but i still struggle.
Is it possible to build a query up in stages?
Let's say I have a search form with many text and select fields that may be chained with and/or or which could be blank.
So the sql statement should consist of several parts that are connected individually for each search.
I tried to create strings for every option and put them to a symbol? (i mean #options) and put that in the where clause (e.g. Product.where(#options) ). That works somehow but i have got troubles with this part: 'params[:query]' when it's in quotes. Either my sql statement says 'select products from products where (name like params[:query]') or if i try #{params[:query]} it says: select products from products (where 'name' like ''.)
So how can i chain different parts of a query?
I looking forward to your answers!
Never, ever, ever embed raw strings in your SQL. This is extremely bad form. You should always use the escaping mechanism provided by Rails or something equivalent to avoid ending up in serious trouble. Inserting content from params is very dangerous and should never be done as it only takes this to nuke your app: { :query => '\"-- DROP TABLE users;' }
Generally you use the helper methods provided by ActiveRecord to build up your query in stages:
scope = Product
if (params[:query].present?)
scope = scope.where([ 'name LIKE ?', "%#{params[:query]}%" ])
end
if (params[:example].present?)
scope = scope.where(:example => true)
end
#products = scope.all
You can build it up in stages like this, modifying the scope in-place each time, and then execute the final call to retrieve it. Generally that's when you use your paginator to split up the results.
It's okay to put pretty much anything in your options because it should be escaped by the time it hits the SQL phase, much as anything on the HTML side is escaped for you as well.
Don't confuse instance variables like #options with a symbol like :query. The two are very different things. Instance variables have the benefit of propagating to your view automatically, so they are often used extensively in controllers. Views should avoid modifying them whenever possible as a matter of style.

Iterating through array of Models in rails

Yet another ruby question but this is a bunch of questions in one. I'm really starting to like rails but there are some questions that I'd just like to ask straight out.
Right now, I'm implementing a queue in sqlite. I already have a scaffold setup with this working OK. The purpose is for a web crawler to read through the array and determine which links he should crawl next.
The architecture in the program is 2 controllers. one for Job and one for crawler. The Jobs has the standard Crud interface supplied by scaffold. Where I'm falling down is I'm still trying to understand how these things communicate with eachother.
The Job is formatted as a url:string and depth:decimal. The table is already populated with about 4 objects.
#sitesToCrawl = Job.all
#sitesToCrawl.each {|x|puts Job.url}
I have a bunch of questions about the above.
At the moment, this was supposed to display all the jobs and I foolishly thought it would display plain text but its actually a hexidecimal pointer to the object itself. What Im trying to do is iterate through the #sitesToCrawl and put out each Jobs url.
Questions start here:
1: I know ruby is dynamically typed. Will #sitesToCrawl become an array like i want it to be with each slot containing a job.
2: #sitesToCrawl.each is pretty straighforward and I'm assuming its an iterator.
is X the name od the method or what is the purpose of the symbol or string between |*|
3: Puts and print are more or less the same yes? if i say #x = puts 3 then would x be 3?
4: Job.url. Can objects be referenced this way or should I be using
##sitesToCrawl = db.execute("SELECT url FROM jobs;")
where db is a new database
As Rubish Gupta pointed out, in your block, you should do x.url, otherwise you're trying to access the url method on the class Job, not on instances of Job. In other words, in blocks, the items in the pipes are the arguments of the block, and each will iterate through your array, passing in one item at a time to your block. Check out the doc here.
Just to extend this idea, each on Hashes (associative arrays, maps, whatever you know them as) will pass two variables to your block: a key and a value, like this:
a_hash.each {|key_var, val_var| puts "#{key_var} is associated with #{val_var}"}
Also, it's been a bit since I've done plain ActiveRecord models, but you might look into doing
#sitesToCrawl = Job.all.to_a
since Job.all is a lazy finder in that it's building a query in potentia: you've essentially built a query string saying SELECT * FROM jobs, but it might not be executed until you try to access the items. each might do that, I can't remember off the top of my head, but if you're using a debugger to look at it, I know you need to_a to get it to run the query.
You should absolutely be using job_instance.url - that's the beauty of ActiveRecord, it makes database access easy, provided everything gets set up right :)
Finally, puts and print are almost the same - the difference is that puts "string" is essentialy print "sting"; STDOUT.flush - it flushes at the end of the statement.

Resources