Rails Security

I read a post in another blog today about SQL Injection in Rails. The poster raised the specter of insecure code making the database vulnerable through the use of SQL Injection.

For those that don’t know, SQL Injection is where an attacker ‘injects’ code into a web response that makes the site return data that it was not designed to. SQL servers will try to parse any query that they receive, so it is up to the programmer to ensure that anything a hacker might throw at a database gets rejected before the query reaches the SQL Server. Sometimes, despite the best intentions of the coder, a vulnerability gets exposed in the Rails framework at which point it might might be necessary to do some urgent work to address the issue.

The post mentioned above did nothing to explain how to address the issue of SQL Injection in Rails; instead it was a hook to get the reader to attend a particular talk at an upcoming Rails conference. That’s not a lot of help if you can’t attend the event.

Giving thought to Security Vulnerabilities is something that doesn’t often come naturally to coders; especially self taught ones. A bit like Testing, it’s not at the glamorous end of development and too often gets overlooked. Now security issues have been around for as long as people have written code and others have tried to hack it, so addressing potential security vulnerabilities by using good coding practice must be part of the development process.

Many good people have already written much good stuff on this topic, so I’m not going to add to it. Instead, I’ll point you in the direction of a few sites that I consider will be of the best help to you and exhort you to take the issue of the security of your web site very seriously. There’s absolutely no point in producing a wonderful looking site that uses all sorts of gee-whiz effects if your client is going to find that their site or their database is going to be hacked.
The following links take you to existing sites that deal with Rails Security in an excellent manner:

  • http://guides.rubyonrails.org/security.html – This is the Security page on the Rails site and these people know what they are talking. Read and re-read until you understand what the issues are and how to deal with them.
  • http://railscasts.com/ – Ryan Bates’ Railscasts site contains a whole host of material pertaining to development in the Rails environment and some of it is devoted to security issues. The Pro subscription costs $9 a month but as a Rails developer you’ll never spend a better $9.
  • http://rails-sqli.org/ – This site is devoted to what not to do when coding in Rails. It’s very well worth taking a look at this.
  • https://groups.google.com/forum/#!forum/rubyonrails-security – This is the source that you need to subscribe to if you can’t find the help you need. Very friendly advice given from participants.
  • http://brakemanscanner.org/ – This is a gem in the real sense of the word. An Open Source Rails Security Scanner that you can include in your gem list. See http://railscasts.com/episodes/358-brakeman for an excellent Railscast on how to use.
  • https://isc.sans.edu – A bit over the top for this post perhaps; you’ll need to sign up for this (although it costs nothing) before you’ll be able to search for Rails specific issues.

I hope at least one of the above links helps!

Rejoining the Tracks

I’ve been away from Ruby and Rails for a long time so before I started working in the environment again, I thought it best to ensure my iMac was up to date with the appropriate software.
If you’re at all serious about using Ruby as a development tool, I sincerely recommend using ‘rvm’ to manage your Ruby versions (as you’ll already know if you’ve read any of my other posts!). Ruby is in continuous development and unlike some languages, it is often the case that the syntax in a new version of Ruby might break code that runs perfectly in an earlier version of the language.
A Ruby Version manager is therefore essential to anybody who works in the Ruby development space for any length of time. rvm is perfect for the job and there are extensive instructions there to cope with installations on OSX, Ubuntu and Windows. I haven’t checked but I’m sure that anybody running a Unix flavor other than Ubuntu would also be able to find help if required.
The first thing I did was update rvm. A quick look on the rvm site told me that the update command was still

rvm get stable

which ran perfectly.
I then checked which Rubies I had installed, noting that Rails 4 (my intended destination) preferred Ruby 2.0.0.
Ruby 2.0.0 was not on my system, so I tried to install it using

rvm install 2.0.0

which immediately produced an error.
Checking the appropriate log file showed the following:

Warning: The Command Line Tools for Xcode don't appear to be installed; most ports will likely fail to build.

(Yes, XCode is required (for its compiler), so install it if you haven’t done so already.)
So, XCode CLI first; that was strange as I knew that I’d downloaded the XCode app from the Apple app store recently.
I ran XCode and realized the problem – downloaded but not installed. On first run, XCode opens the Preferences -> Downloads window from which you can select items to, err, download. The Command Line Tools are not selected by default, so click on them and wait for the CLI to be installed.
I then turned to MacPorts and tried to run

sudo port -v selfupdate

but got an error message. I vaguely remembered having a problem with MacPorts last time I tried to install Ruby 2.0, so I decided to try a clean install.
The MacPorts site has a link for users of various flavors of OSX so I ran the one for Mountain Lion and got an ‘Installation Successful’ message.
Just to make sure, I tried

sudo port -v selfupdate

again, and got the message

---> MacPorts base is already the latest version

The ports tree has been updated. To upgrade your installed ports, you should run
port upgrade outdated

so I ran

port upgrade outdated

as suggested and received a couple of warnings about uninstall being forced for ‘readline’ and ‘freetds’ but got

---> No broken files found.

in the end.

rvm install 2.0.0

then ran without a hitch.
Just to tidy up, I added

source $HOME/.rvm/scripts/rvm

to the end of my .bashrc script. If it is not clear, adding this line to the .bashrc script (which runs every time a Terminal window is opened) enables rvm scripts to run by simply typing e.g.,

rvm help

or

rvm info

Looking at the contents of the
~/.rvm/scripts/rvm folder in Finder shows just how many scripts there are available
Then I ran

rvm alias create default 2.0.0

(which is one of the above mentioned scripts) to set Ruby 2.0.0 as the default Ruby version when I open a Terminal window.
To illustrate, when I open a Terminal window and run either Ruby or irb, I get the following:

martin@polaris:~ ruby -v
ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.3.0]
martin@polaris:~ irb
2.0.0-p247 :001 >

One thing that rvm does not do is create the documentation on an install (see http://rvm.io/rubies/docs). This can be checked by attempting to use ri, e.g:

martin@polaris:~ ri Hash
Nothing known about Hash

I fixed this by running

rvm docs generate

However, doing so generated a warning:

Warning! PATH is not properly set up, '/Users/martin/.rvm/gems/ruby-2.0.0-p247/bin' is not at first place,
usually this is caused by shell initialization files - check them for 'PATH=...' entries,
it might also help to re-add RVM to your dotfiles: 'rvm get stable --auto-dotfiles'

so, once the doc build had finished, I ran

rvm get stable --auto-dotfiles

as suggested, which ran successfully and printenv showed that the path had been amended for the terminal window with the Ruby files at first place.
Lastly, the process produced information that might often be ignored, so I thought I’d include it here:

# In case of problems:
# run and read: rvm notes
# read docs: http://rvm.io/
# talk to us: http://webchat.freenode.net/?channels=rvm (http://freenode.net/faq.shtml#plusr)
# read cheatsheet: http://cheat.errtheblog.com/s/rvm
# watch screencast: http://screencasts.org/episodes/how-to-use-rvm
# open a bug report: https://github.com/wayneeseguin/rvm/issues

Rails Date Formats

First published on Fencore Ltd.’s Posterous page on December 3rd, 2010

(Note that the comment about working in Britain is no longer true, as I now reside in the USA.)

I don’t know about you but I get confused when working with dates as the built-in formats don’t work for me.
Ruby has a Date library that implements both the Date and DateTime classes and Rails extends these in its ActiveSupport library. There is also a Time class and, of course, these things cannot exist in isolation from each other.
As I work in Britain, I need to be able to produce dates in British format. I add custom formats to the Rails DATE_FORMATS hash by creating a file in config/initializers with the following contents:

Date::DATE_FORMATS[:british] = "%d/%m/%Y"
Date::DATE_FORMATS[:british_long] = "%d %B, %Y"
Date::DATE_FORMATS[:british_long_ordinal] = lambda { |date|
date.strftime("#{ActiveSupport::Inflector.ordinalize(date.day)} %B, %Y") } # => "25th April, 2007"

According to the documentation (for Rails 3.0.3 look at the ActiveSupport RDocs and then for to_formatted_s(format = :default) in DateTime), the file should be called config/initializers/time_formats.rb but it turns out that is is more of a suggestion than a ‘must do’. I found this out when I called I called it date_formats.rb by mistake; in fact I tried calling it splat.rb and it still worked, so perhaps something a little more generic like date_time_formats.rb would be better.
With that in place, and noting that to_formatted_s is aliased to to_s, you can do things like:

> date = Date.today => Fri, 03 Dec 2010
> date.to_s # this is the default output
=> "2010-12-03"
> date.to_s(:long) # this is pre-defined
=> "December 3, 2010"
> date.to_s(:british)
=> "03/12/2010"
> date.to_s(:british_long)
=> "03 December, 2010"
> date.to_s(:british_long_ordinal)
=> "3rd December, 2010"

You can do a similar thing with times (although I find no need to) and of course, you can define your own formats to satisfy your own local needs.
What about converting from a string to a Date or DateTime object?
Well, the strptime method is part of the Ruby language, so the following works:

> Date.strptime("31/01/2010", "%d/%m/%Y")
=> Sun, 31 Jan 2010 DateTime.strptime("31/01/2010", "%d/%m/%Y")
=> Sun, 31 Jan 2010 00:00:00 +0000

Note that I am using Ruby 1.9.2, although I believe nothing has changed from 1.8.x

Ruby Snippet – next day of week given date

First published on Fencore Ltd.’s Posterous page on October 13th, 2010

I needed the ability to work out the date of the next weekday after a given date, e.g. what is the date of the Saturday after the 1st December? The following will do it:

#date_convert.rb
require 'date'
require 'active_support/core_ext'
Date::DATE_FORMATS.merge!({british: "%d/%m/%Y"})
class DateConvert
  # usage:
  # date_of_next( day_name, date) where day_name is a string or symbol representation of a full weekday name, e.g. :saturday
  # and date is either a valid Date object or a string representation of a date
  def date_of_next( day_name, date = Date.today.to_s(:british))
    # Note that config/initializers/date_formats.rb has been created with the following lines:
    # Date::DATE_FORMATS[:british] = "%d/%m/%Y" # => 25/4/2007
    # Date::DATE_FORMATS[:british_long] = "%d %B, %Y" # 25 April 2007
    # Date::DATE_FORMATS[:british_long_ordinal] = lambda { |date| date.strftime("#{ActiveSupport::Inflector.ordinalize(date.day)} %B, #
    # day_name must be a string value representing the full day name (or a token equivalent)
    # date must be a valid Date
    #
    # date_of_next( "saturday") is valid
    # date_of_next( "Saturday") is valid
    # date_of_next( :Saturday) is valid
    # date_of_next( "sat", Date.today) is invalid - invalid day_name
    # date_of_next( :saturday, "2010/11/31")) is invalid - ArgumentError: invalid date
    #
    date = date.to_s(:british) if date.kind_of?(Date)
    which_day = (day_name.downcase.to_s + "?").to_sym
    (1..7).each do |inc|
      begin
        date_object = Date.strptime(date, "%d/%m/%Y")
        return date_object + inc if (date_object + inc).send(which_day)
      rescue
        puts "Enter the day as a string or symbol representation of a full weekday name, e.g. :saturday"
        puts "Enter the date as a string value of the form dd/mm/yyyy"
        return
      end
    end
  end
end

require '/Users/martin/work/utils/date_convert.rb'
describe DateConvert, "#date_of_next" do
  before(:each) do
    @dc = DateConvert.new
  end
  it "returns a date object when given a valid day of the week as a string" do
    @dc.date_of_next("saturday").should be_an_instance_of(Date)
    @dc.date_of_next("Saturday").should be_an_instance_of(Date)
  end
  it "returns a date object when given a valid day of the week as a symbol" do
    @dc.date_of_next(:saturday).should be_an_instance_of(Date)
  end
  it "returns a date object when given a valid day of the week and a valid date as a string" do
    @dc.date_of_next("saturday", "9/11/2010").should be_an_instance_of(Date)
  end
  it "returns a date object when given a valid day of the week and a valid date as a Date object" do
    @dc.date_of_next("saturday", Date.today).should be_an_instance_of(Date)
  end
  it "raises an exception when given a valid day of the week and a invalid date as a string" do
    @dc.date_of_next("saturday", "2010/11/9").should raise_exception()
  end
  it "raises an exception when given a day of the week in invalid format" do
    @dc.date_of_next("sat", "9/11/2010").should raise_exception()
  end
  it "returns a date for next saturday that should be a Saturday" do
    @dc.date_of_next("saturday").should be_a_saturday
  end
  it "returns a date for next sunday that should be a Sunday" do
    @dc.date_of_next("sunday").should be_a_sunday
  end
  it "returns a date for next saturday after '9/11/2010' that should be '13/11/2010'" do
    @dc.date_of_next("saturday", '9/11/2010').to_s(:british).should == '13/11/2010'
  end
end

Hope it helps.

no such file to load — .bundle/environment (LoadError)

First published on Fencore Ltd.’s Posterous page on October 13th, 2010

As part of the confusion I caused for myself last week (see https://martinjhawkins.wordpress.com/2013/10/08/installing-ri-documentation-for-rails-3-0-0-file-not-found-lib-and-rvm), I managed to include a fight with Textmate.
I use Cucumber and I run the features from within Textmate; for me the information is presented far better than it is on the command line.
After I’d installed rvm and re-installed the gems, using Bundler, I proceeded to check that testing was working as it had been. So, I loaded everything into Textmate, opened a feature window and hit Command-r. Instead of the results window I got an error trace, in which was the following: ‘no such file to load -- .bundle/environment (LoadError)‘.
So – off to look at the .bundle folder – no sign of an environment.rb file. Look at the Bundler web site – nothing there. Google the error – yes, some other people have seen it but there don’t seem to be any magic fixes.
Off to the rvm site again; check that rvm is installed properly – yes; check that all the actions mentioned under Integration/Textmate have been completed yes. I’m beginning to get that horrible sinking feeling that I’ve broken something serious.
On a whim, I created an empty .bundle/environment.rb file and tried to run the feature again – and lo – it worked! I have no idea what this file actually does in the grand scheme of things but the unfortunate thing was that it got deleted every time I ran a feature test. I was not going to recreate it every time.
Time for a re-install.
Cucumber.tmbundle‘ lives in the ~/Library/ApplicationSupport/TextMate/Bundles/ folder, so I deleted it and re-installed it using the instructions on the ‘http://github.com/drnic/cucumber-tmbundle‘ page. Re-loaded Bundles in Textmate and now nothing worked. The only thing that showed up in the Cucumber bundle now was ‘Switch to new Canonical Fork’. Eh? That wasn’t there before and was certainly not what I wanted.
Cue an even deeper sinking feeling.
I took a careful look at what I’d done. I’d copied the instructions from http://github.com/drnic/cucumber-tmbundle without paying too much close attention and realised that was the error.
Drnic has taken over the development of the Cucumber.tmbundle from Ben Mabey, who created it but who no longer used it. Rather than let it whither and die he passed it across to Drnic. In cloning the site, a basic error was made – the important line in the instructions refer to the old site. In order to make the install work properly, you need to replace the line that says

git clone git://github.com/bmabey/cucumber-tmbundle.git Cucumber.tmbundle

with

git clone http://github.com/drnic/cucumber-tmbundle.git Cucumber.tmbundle

Once I’d realised that mistake, I re-installed and everything worked fine.

Installing ri documentation for rails-3.0.0… File not found: lib and rvm

First published on Fencore Ltd.’s Posterous page on October 13th, 2010

I’ll put the bottom line first: if you’ve tried installing Rails 3 and received an ‘Installing ri documentation for rails-3.0.0… File not found: lib’ error and ended up with no Rdocs, you need to install the rdoc gem first. If you do that, the problem goes way and the install will work perfectly.
I’d been working on a Rails application for some time and had been using it as a learning experience – trying all sorts of new ideas but the wheels fell off last week.
Rails 2.3.8 had been producing lots of deprecation warnings and seeing that 2.3.9 addressed some of those, I thought I’d upgrade. Easy enough – download the new gems (and incidentally clog up my gem repository even more) make a couple of trivial changes to the environment.rb file and try it out. No issues so far.
I needed to move the application to a Windows box and tried freezing the gems into the vendor directory and then copying it across, having installed MySQL and used the Windows Ruby Installer. No luck this time; it’s been a long while since I’ve run Rails on a Windows box but it seems an even less friendly environment than it used to. Apparently the Ruby installer is compiled using a different compiler nowadays and some gems haven’t changed along with it. I needed to install different versions of some gems.
Recognising the existence of rvm, which allows different versions of Ruby to run on the same computer (although you need to use ‘pik’ on a Windows computer), and also of the Bundler gem, which is integral to Rails 3 and allows for better management of gems, I decided to try these out.
Too many changes at once? Darn right. Hindsight is a wonderful thing…
If you follow the instructions carefully, rvm installs easily enough. You can install different versions of Ruby and install different gems for each Ruby version. (rvm calls these gemsets).
In fact, rvm goes further than this – it enables the creation of many gemsets under each Ruby version, allowing you to create gemsets for specific applications. When using a specific gemset, you also have access to a global gemset under that Ruby version. Neat!
Using a file called .rvmrc, you can set things up so that a default Ruby and gemset are chosen when you ‘cd’ to a particular directory.
rvm is an excellent utility and full marks must go to Wayne Seguin and his helpers for developing it. My only carp is about the web documentation, which I really do not like but this is open source right? Live with it or offer to help out!
I did have one huge issue, however. After I had got everything installed to my satisfaction (or so I thought), I tried installing Rails 3.
Now, according to the Rails 3 web site, http://rubyonrails.org/download, you need Ruby, Rubygems and then you can install Rails. If you do and you do not have the rdoc gem installed (which will happen if you use rvm), you will get the error described. Rails will install and work, but you won’t have the documentation locally available. So make sure you have the rdoc gem installed first. (rdoc is also part of Ruby’s standard lib and Rubygems is supposed to install it too – so I guess someone’s not testing enough!)
I have set things up so that the following are available in the global gemset under Ruby-1.8.7; bundler, rake, rdoc, rdoc-data, and syntax. Rake is provided by the rvm setup; the rvm documentation had also stated that rdocs would be installed by default but this wasn’t the case and the rvm web site has had been amended to reflect that.
In my opinion, the Rails site should state that the rdoc gem needs to be installed before Rails (or better yet, make it transparent by including it in the Rails install itself). I’ve tried raisng the issue but so far the response has been that rdoc is not a Rails dependency…

Adding a line break to a Rails confirm message

First published on Fencore Ltd.’s Posterous page on July 13th, 2010

In Rails 2.3.8, the following is produced by the scaffold generator:

<td><%= link_to 'Destroy', common_contents, :confirm => 'Are you sure?', :method => :delete %></td>

If you want to break the ‘confirm’ message over multiple lines, it is important to note that the generator has enclosed the message in single quotes. To make the line break, use \n and change the single quotes to double quotes.

<td><%= link_to 'Destroy', common_contents, :confirm => "Danger/nAre you sure?", :method => :delete %></td>

You’ll then get

2010.7.13.fig1

Instead of

2010.7.13.fig2