Is SQL Injection possible here? - ruby-on-rails

I have run a static code analysis tool (brakeman) on a rails app and it has reported some SQL Injection vulnerabilities which I suspect may be false positives. The offending lines look like this:
#things_controller.rb
def index
Thing.select(params[:columns]).where(params[:conditions])
end
I can't figure a way to exploit this, but it does seem rather open-ended, is this safe enough (this controller requires admin access anyway) or can it be exploited?
Ruby is 2.0.0-p247,
Rails is 4.0.0

While rails has some built-in filters for special characters, this is definitely vulnerable:
http://guides.rubyonrails.org/security.html#sql-injection
If you want to test it yourself, run a full scan with sqlmap using the url of this action with a conditions GET parameter

Related

methods for debugging slow queries in active model serializers?

I am having difficulty optimizing my Active Model Serializers to avoid the n+1 problem. As per suggestions from their docs, I have attempted to eager load the associations which i thought were causing my query bottlenecks, but my serializers are still taking forever.
Obviously, i must be doing something wrong. My application is deeply nested with associations, so i guess I'm more interested in discovering a tool to unveil to me exactly WHICH associations are costing me. Right now, i am attaching a stack trace to every query run through the ActiveRecord
ActiveSupport::Notifications.subscribe("sql.active_record") do |_, _, _, _, details|
puts caller.join("\n")
puts "*" * 50
end
which gives me a ridiculous output because i am running so many queries to begin with, but, in addition, the stack traces are not helpful at identifying which serializer is at fault. It shows me which controller method was calling render, but then from there the stack trace simply prints methods from gems/active_model_serializers, which does not help me.
I am hoping to uncover a method of debugging that would be able to identify to me which serializers were at fault, that way i am not guessing at how to optimize my queries. Has anybody discovered anything like this? Thanks!
===================
UPDATE
Just so it is clear, i am already printing a query log, in addition to a stack trace. Unfortunately, with so many associations to keep track of, the query log is not exactly helpful at identifying the source of the query. It is guess work at best, and ineffective at the association scope i am dealing with.
I have abandoned the stack traces altogether, finding them to be totally unhelpful. Now, all i have printing are SQL logs, and i am manually sifting through them, trying to discover the source of the association.
The next method I will attempt (although i hate to resort to it) is commenting out associations until i see improvements in my query times. It will be more effective than trying to trace the source of the problem, but it will provide me no comfort in a production environment (where commenting out critical associations is not an option), so if anybody finds a solution that can help, I would still be very grateful.
I will continue to post updates as I move through this problem, as it may help many others in the future.
======================UPDATE 2
It turns out that commenting out associations in my serializer and reintroducing them one at a time, while ineffective in production, is an excellent way to debug in a local environment. I was able to drill down to the problem within a minute and correct it. Still, this is not an ideal solution. I would ideally like to be able to identify the problem from a log so that in production i could ascertain the issue without affecting the application's behavior.
The active_record_query_trace gem can do that.
Add the following to your Gemfile:
group :development do
gem 'active_record_query_trace'
end
Create an initializer such as config/initializers/active_record_query_trace.rb to enable the gem. If you want to customize how the gem behaves, you can add any combination of the options described in the docs to the initializer as well.
if Rails.env.development?
ActiveRecordQueryTrace.enabled = true
# Optional: other gem config options go here
end
Restart the Rails development server.
Easy way within any gems - is logging each string of code. For example, if you have
that code of serializer:
module Flats
class IndexSerializer < Api::V2::RealtyObjects::IndexSerializer
attributes(
:flat_number,
:entrance_number,
:floor_in_house,
:live_area,
:room_count,
:total_area,
)
end
end
add method which will be log time to your development.log on each attribute:
module Flats
class IndexSerializer < Api::V2::RealtyObjects::IndexSerializer
attribute_list = %i[
flat_number
entrance_number
floor_in_house
live_area
room_count
total_area
]
attributes(*attribute_list)
def logger(name, value)
Rails.logger.debug name, value, "#{Time.now.strftime('%M:%S--%N')}"
end
attribute_list.each do |attribute_name|
define_method attribute_name do |value|
logger(attribute_name, value)
super
end
end
end
end

Logging all method calls in a Rails app

Is there an easy way to log all method calls in a Rails app?
My main use for this would be in testing (and in debugging tests). I want to have more of a history than a stacktrace provides (for instance, when running rspec with the '-b' option).
It's easy to do. Just add 5 lines of code into your script/server:
#!/usr/bin/env ruby
set_trace_func proc {
|event, file, line, id, binding, classname|
if event == "call" or event == "return"
printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
end
}
require File.expand_path('../../config/boot', __FILE__)
require 'commands/server'
It's described at http://phrogz.net/ProgrammingRuby/ospace.html#tracingyourprogramsexecution
Your application will become quite slow and you might get more output than you want. You can easily add more conditions on file/class/function names to avoid printing unwanted stuff.
Perftools might give you what you're looking for. It analyzes the entire process and can give you a graphical view that looks something like this. Rack perftools profiler is a rubygem that uses perftools and makes it easy to integrate with a Rails application, so I would recommend going with that if you want to try it.
Firstly stacktrace IS every method call that was on the stack at the time an error occurred, what other history could you want besides this?
Secondly, to answer your question, no there is no easy way to log all method calls. You could up your log level all the way to debug which should give you more stuff in the logs, but this will only be things that someone has actually chosen to log, unrelated to method calls.
It probably wouldn't be that difficult to patch ruby in such a way that every method call will print some log statements before and after the method execution, but this will once again be similar to what a stack trace would give you anyway and potentially less since you won't get line numbers etc.
If you want more info than the stack trace, logging is the way most people would do it.

"Correct" way to write log output from a background (Resque) job?

Resque jobs are just plain old ruby objects. I can use puts calls inside them to produce output into the console, or I can instantiate a standard Ruby Logger class with STDOUT and use that.
But is there a correct approach to logging in Rails, from places that aren't controllers or models? I see Rails.logger returns a BufferedLogger, but when I call info or warn etc on it, nothing happens. If I call flush on it, it just returns an empty array and nothing is output.
What's the convention here?
I'm not really sure that there is a convention. I had a pretty ugly logging system up until just recently. Now I use lumber to integrate log4r with Rails. That really made logging much nicer because I now have named loggers (e.g., logger matches the class name -- great for filtering output) and I can control log levels on a per-logger (i.e., per-class) basis.
There's also a GELF adapter for log4r if you want to use graylog2 to aggregate your logs.

How to skip certain tests with Test::Unit

In one of my projects I need to collaborate with several backend systems. Some of them somewhat lacks in documentation, and partly therefore I have some test code that interact with some test servers just to see everything works as expected. However, accessing these servers is quite slow, and therefore I do not want to run these tests every time I run my test suite.
My question is how to deal with a situation where you want to skip certain tests. Currently I use an environment variable 'BACKEND_TEST' and a conditional statement which checks if the variable is set for each test I would like to skip. But sometimes I would like to skip all tests in a test file without having to add an extra row to the beginning of each test.
The tests which have to interact with the test servers are not many, as I use flexmock in other situations. However, you can't mock yourself away from reality.
As you can see from this question's title, I'm using Test::Unit. Additionally, if it makes any difference, the project is a Rails project.
The features referred to in the previous answer include the omit() method and omit_if()
def test_omission
omit('Reason')
# Not reached here
end
And
def test_omission
omit_if("".empty?)
# Not reached here
end
From: http://test-unit.rubyforge.org/test-unit/en/Test/Unit/TestCaseOmissionSupport.html#omit-instance_method
New Features Of Test Unit 2.x suggests that test-unit 2.x (the gem version, not the ruby 1.8 standard library) allows you to omit tests.
I was confused by the following, which still raises an error to the console:
def test_omission
omit('Reason')
# Not reached here
end
You can avoid that by wrapping the code to skip in a block passed to omit:
def test_omission
omit 'Reason' do
# Not reached here
end
end
That actually skips the test as expected, and outputs "Omission: Test Reason" to the console. It's unfortunate that you have to indent existing code to make this work, and I'd be happy to learn of a better way to do it, but this works.

Rails 3 : Anticipating migration for 2.3 beginners

I am a beginner in Rails. I use 2.3.X.
I just saw Rails 3 is pre-released [edit: now in release candidate!]. I will most probably eventually switch to it.
What are the common coding habits in 2.3 I should not take, so that the switch is as smooth as possible ?
Edit:
I've done my homework and read the Release notes. But they are far from clear for the most crucial points, for example :
1.5 New APIs
Both the router and query interface have seen significant, breaking changes. There is a backwards compatibility layer that is in place and will be supported until the 3.1 release.
This is not comprehensive enough for a beginner like me. What will break ? What could I do already in 2.3.X to avoid having troubles later ?
Looking at my personal coding habits (I have been using Rails since 1.2.x), here's a list of API changes you can anticipate according to Rails 3 release notes.
find(:all)
Avoid the usage of:
Model.find(:all)
Model.find(:first)
Model.find(:last)
in favour of:
Model.all
Model.first
Model.last
Complex queries
Avoid the composition of complex queries in favor of named scopes.
Anticipate Arel
Rails 3 offers a much cleaner approach for dealing with ActiveRecord conditions and options. You can anticipate it creating custom named scopes.
class Model
named_scope :limit, lambda { |value| { :limit => value }}
end
# old way
records = Model.all(:limit => 3)
# new way
records = Model.limit(3).all
# you can also take advantage of lazy evaluation
records = Model.limit(3)
# then in your view
records.each { ... }
When upgrading to Rails 3, simply drop the named scope definition.
Constants
Avoid the usage of the following constants in favour of the corresponding Rails.x methods, already available in Rails 2.x.
RAILS_ROOT in favour of Rails.root,
RAILS_ENV in favour of Rails.env, and
RAILS_DEFAULT_LOGGER in favour of Rails.logger.
Unobtrusive Javascript
Avoid heavy JavaScript helpers in favour of unobtrusive JavaScript.
Gem dependencies
Keep your environment.rb as clean as possible in order to make easier the migration to Bundler. You can also anticipate the migration using Bundler today without Rails 3.
The release notes are the most important thing to keep an eye on. Other than that Jeremy McAnally has some neat blog posts about the whole Rails 3 thing (and has just released a gem to help you with the migration).
I'd say, read the rails release notes and see for yourself what seems the more surprising to you. A lot of stuff changed so reading this is definitively very important.

Resources