This document summarizes best practices for securing Rails applications. It discusses potential information leaks from server headers, status pages, and Subversion metadata. It also covers vulnerabilities like cookie session storage, cross-site scripting (XSS), session fixation, cross-site request forgery (CSRF), SQL injection, and JavaScript hijacking. The document provides recommendations to address each issue, such as disabling server headers, preventing .svn access, using secure session storage, sanitizing user input, resetting sessions after login, validating CSRF tokens, and escaping values in SQL queries.
4. Agenda
Follow the application stack
and look for
Setup and deployment
• Information leaks
Application code
• Possible vulnerabilities
• Security best practices
Framework code
Rails Application Stack
4
4
12. Information leaks
Is the target application a Rails application?
• Default setup for static files:
/javascripts/application.js
/stylesheets/application.css
/images/foo.png
• URL schema
/project/show/12
/messages/create
/folder/delete/43
/users/83
12
13. Information leaks
Is the target application a Rails application?
• Rails provides default templates for 404 and 500 status pages
• Different Rails versions use different default pages
• 422.html only present in applications generated with Rails >= 2.0
• Dispatcher files not present in recent Rails versions
13
14. Sample Status Pages
http://www.twitter.com/500.html http://www.43people.com/500.html
http://www.engineyard.com/500.html Rails >= 1.2 status 500 page
14
15. Server Header
GET http://www.haystack.com
Date: Wed, 28 Oct 2009 11:23:24 GMT
Server: nginx/0.6.32
Cache-Control: max-age=0, no-cache, no-store
…
GET https://signup.37signals.com/highrise/solo/signup/new
Date: Wed, 28 Oct 2009 11:54:24 GMT
Server: Apache
X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.5
Status: 200 OK
…
15
16. Server Header
GET http://www.twitter.com
Date: Wed, 28 Oct 2009 11:23:24 GMT
Server: hi
Status: 200 OK
…
GET http://www.golfermail.org
Date: Wed, 28 Oct 2009 11:13:41 GMT
Server: Mongrel 1.1.5
Status: 200 OK
…
Disable Server header
# httpd.conf
Header unset Server
Header unset X-Powered-By
16
17. Information leaks
Subversion metadata
• Typically Rails applications are deployed with Capistrano / Webistrano
• The default deployment will push .svn directories to the servers
GET http://www.strongspace.com/.svn/entries
…
dir
25376
http://svn.joyent.com/joyent/deprecated_repositories/www.strongspace/trunk/public
http://svn.joyent.com/joyent
Prevent .svn download
2006-04-14T03:06:39.902218Z <DirectoryMatch "^/.*/.svn/">
34 ErrorDocument 403 /404.html
justin@joyent.com Order allow,deny
Deny from all
…
Satisfy All
</DirectoryMatch>
17
18. Cookie Session Storage
Since Rails 2.0 the session data is stored in the cookie by default
Base64(CGI::escape(SESSION-DATA))--HMAC(secret_key, SESSION-DATA)
18
19. Cookie Session Storage
Security implications
• The user can view the session data in plain text
• The HMAC can be brute-forced and arbitrary session data could be created
• Replay attacks are easier as you cannot flush the client-side session
Countermeasures
• Don’t store important data in the session!
• Use a strong password,
Rails already forces at least 30 characters
• Invalidate sessions after certain time on the server side
… or just switch to another session storage
19
21. Cross-Site Scripting - XSS
“The injection of HTML or client-side Scripts (e.g. JavaScript) by malicious users into
web pages viewed by other users.”
21
22. Cross-Site Scripting - XSS
Cases of accepted user input
• No formatting allowed
search query, user name, post title, …
• Formatting allowed
post body, wiki page, …
22
23. XSS - No Formatting Allowed (Rails 2.x)
Use the Rails `h()` helper to HTML escape user input
But using `h()` everywhere is easy to forget.
Better, use safeERB, XSS Shield, or rails_xss plugins:
http://agilewebdevelopment.com/plugins/safe_erb
http://code.google.com/p/xss-shield/
http://github.com/NZKoz/rails_xss
23
24. XSS - No Formatting Allowed (Rails 3)
Rails 3 auto escapes strings in RHTML template
Explicitly mark strings as HTML safe
24
25. XSS - No Formatting Allowed (Rails 3)
rails_xss Plugin
• Build-in in Rails 3
• Introduces “Safe Buffer” concept
• Updates all the helpers to mark them as html_safe!
• Requires Erubis
Install and get familiar with if on Rails 2.x
http://github.com/NZKoz/rails_xss
25
26. XSS - Formatting Allowed
Two approaches
Use custom tags that will translate to HTML (vBulletin tags, RedCloth, Textile, …)
Use HTML and remove unwanted tags and attributes
• Blacklist - Rails 1.2
• Whitelist - Rails 2.0
26
27. XSS - Custom Tags
Relying on the external syntax is not really secure
Filter HTML anyhow
27
28. XSS - HTML Filtering
Use the Rails `sanitize()` helper
Only effective with Rails > 2.0 (Whitelisting):
• Filters HTML nodes and attributes
• Removes protocols like “javascript:”
• Handles unicode/ascii/hex hacks
28
32. Session Fixation
Rails uses only cookie-based sessions
Still, you should reset the session after a login
The popular authentication plugins like restful_authentication are not doing this!
32
33. Cross-Site Request Forgery - CSRF
You visit a malicious site which has an image like this
Only accepting POST does not really help
33
34. CSRF Protection in Rails
By default Rails > 2.0 will check all POST requests for a session token
All forms generated by Rails will supply this token
34
35. CSRF Protection in Rails
Very useful and on-by-default, but make sure that
• GET requests are safe and idempotent
• Session cookies are not persistent (expires-at)
35
37. SQL Injection Protection in Rails
Always use the escaped form
If you have to manually use a user-submitted value, use `quote()`
37
38. SQL Injection Protection in Rails
Take care with Rails < 2.1
Limit and offset are only escaped in Rails >= 2.1
( MySQL special case )
38
39. JavaScript Hijacking
http://my.evil.site/
JSON response
The JSON response will be evaled by the Browser’s JavaScript engine.
With a redefined `Array()` function this data can be sent back to http://my.evil.site
39
40. JavaScript Hijacking Prevention
• Don’t put important data in JSON responses
• Use unguessable URLs
• Use a Browser that does not support the redefinition of Array & co,
currently only FireFox 3
• Don’t return a straight JSON response, prefix it with garbage:
The Rails JavaScript helpers don’t support prefixed JSON responses
40
43. Mass Assignment
Use `attr_protected` and `attr_accessible`
Vs.
Start with `attr_protected` and migrate to `attr_accessible` because of the different
default policies for new attributes.
43
44. Rails Plugins
Re-using code through plugins is very popular in Rails
Plugins can have their problems too
• Just because somebody wrote and published a plugin it doesn’t mean the plugin is
proven to be mature, stable or secure
• Popular plugins can also have security problems, e.g. restful_authentication
• Don’t use svn:externals to track external plugins,
if the plugin’s home page is unavailable you cannot deploy your site
44
45. Rails Plugins
How to handle plugins
• Always do a code review of new plugins and look for obvious problems
• Track plugin announcements
• Track external sources with Piston, a wrapper around svn:externals
http://piston.rubyforge.org/
45
47. Conclusion
Rails has many security features enabled by default
• SQL quoting
• HTML sanitization
• CSRF protection
The setup can be tricky to get right
Rails is by no means a “web app security silver bullet” but adding security
is easy and not a pain like in many other frameworks
47