Ruby on Rails does a decent job in handling security concerns in the background. You will have to configure your application to avoid few security attacks while plugins would be required for many security concerns which are not at all or poorly managed by rails.
In this article I have described the security issues related to a ruby on rails web application. I have followed DRY by linking to articles with good explanation and solutions to security concerns wherever required. This guide can also be used as a quick security check for your current web application.
Authentication is the foremost requirement of most of the web applications to authenticate and give privileges to their users. Apart from normal authentication mechanism rails have plugins for OpenID, CAS and Access Control. Build your own authentication system only if your requirements are very unique or you do not trust other implementations.
Plugin - Restful Authentication (recommended) - easy to use and you can tweak it according to your requirements.The problem arises when metacharacters are injected into your queries to database. Rails has a very good support to avoid SQL injection if you follow conventions in issuing queries to your database.
Description : Alternate Solution - use hash for specifying conditions in#find
To validate the contents of model object before records are created/modified in the database. Activerecord validations are very useful over database data-type constraints to ensure values entered into the database follow your rules. You might have javascript validations for forms but javascript can easily be switched off. Use javascript validations only for better user experience.
Description : Conditional validation using:on
and
:if
options. Checkout this cool video
Be careful using
validates_uniqueness_of, it has problems when used with
:scope
option. Open bug tickets :
:allow_nil
, its quite handy. For ex: set :allow_nil => true
in validates_uniqueness_of to check uniqueness of non-nil values and ignore nil values While creating database records directly from form params, a malicious user can add extra fields into the params and manually submit the web page which will set values of fields which you do not want user to set.
Description : Alternate Solution - Trim the parameters to keep the required keys and remove the others.Use private and protected in controller for methods which should not be actions. Actions are pubic methods and can be invoked from the browser.
hide_action : If non-action controller methods must be public, hide them using hide_action. Be careful of bypassing private and protected using meta-programmingAlways authorize user request. By tweaking form parameters or url a user can send request to view/modify other users information if there is no proper authorization of parameters.
For example : 1 |
## To find information of an order which belongs to a particular user. |
Prevent logs of sensitive unencrypted data using #filter_parameter_logging
in controller. The default behavior is to log request parameters in production as well as development environment, and you would not like logging of password, credit card number, etc.
In a CSRF attack, the attacker makes victim click on a link of his choice which would contain a GET/POST request and causes web application to take malicious action. The link could be embedded in a iframe or an img tag. Its recommended to use secret token while communicating with user to avoid this attack.
Its little complex to understand this attack. So, only those readers who are very enthusiastic to know about it, please read the Description below. Rest can directly move ahead to use the plugin.
Description : Use Get and Post appropiately (note : Both get and post are vulnerable to CSRF) Example - Gmail CSRF security flaw Plugin - CSRF Killer (recommended) - it requires edge railsIf an attacker has session-id of your user, he can create HTTP requests to access user account. An attacker can get session-id by direct access to user machine or is able to successfully run malicious scripts at user machine. In this section we will talk about how to avoid or minimize the risk if attacker has user session-id. Following steps are helpful:
1 |
## Timeout after inactivity of one hour. |
|
ActionController::Base.session_options[:session_expires] = <i>say after two years</i> |
Avoid access to your website from IP addresses which are present in DNS Blacklist(DNSBL).
Plugin - DNSBL checkPage caching does bypass any security filters in your application. So avoid caching authenticated pages and use action or fragment caching instead.
Cross Site Scripting is a technique found in web applications which allow code injection by malicious web users into the web pages viewed by other users. An attacker can steal login of your user by stealing his cookie. The most common method of attack is to place javascript code on a website that can receive the session cookie. To avoid the attack, escape HTML meta characters which will avoid execution of malicious Javascript code. Ruby on Rails has inbuilt methods like escape_html() (h()), url_encode(), sanatize(), etc to escape HTML meta characters.
Description Can we avoid tedious use of h() in views? Sanitize() is used to escape script tags and other malicious content other than html tags. Avoid using it ... its unsecure. Use white_list instead. White_list pluginUse Captcha or Javascript based form protection techniques to ensure only human can submit forms successfully.
When using Captcha do ensure the following :
send_data
and are not stored at the server, because its not required to store images and are redundant. Mailto links in a webpage can be attacked by e-mail harvesting bots. Use the plugin CipherMail to generate a 1024 bit random key and obfuscate the mailto link.
Plugin - CipherMailA lot of people have used password strength evaluators simply because its used by google in their registration form. You can use it to help your users register with strong password. But I don't think its a must have security addon. Uptill now I have not found a good algorithm to assess strength of a password, but some of them are reasonable.
Also, if there is an open source tool or algorithm for evaluating password strength, it can easily be broken. So, you might consider tweaking the algorithm or building one from scratch.
ToolsUse SSL to encrypt sensitive data between transfer from client to server. SSL hits server performace, so you might consider using SSL only for few pages which transfer sensitive data to and fro.
Plugin ssl_requirement Mongrel, rails, apache and SSL Controller in SSL subdomain Sample SSL code in railsBe very careful when you allow your users to upload files and make them available for other users to download.
Description Must read - Section 26.7 of Agile web development with rails - 2nd edition In place file upload 3 plugins for file upload reviewed at :