SECURING
YOUR
GRAILS APP
BEYOND AUTHENTICATION & AUTHORIZATION
whoami
!! DISCLAIMER !!!
This talk is meant to discuss security issues in the spirit of helping those who build systems make stable, secure web applications.
Disclaimer #2
Good Idea
Bad Idea
Building your own security plugin or encryption tools
Using your own security plugin or encryption tools for anything important
Don't
Just don't
Low Effort
Happy Path
Easiest thing possible
MVP
Secure
No unauthorized access.
Hardened
Tested
Low Risk
Grandma's cat photos
Your blog
Static content
Reward
Banking
Health information
Government
Big business
Payment systems
Payment Systems
$$$ of loss potential
Office Space
Loss of consumer confidence
Cat Pictures
Restore the backup
Maybe a few comments lost since last backup
No animals were harmed
Grandma cries for a minute
Building important applications with all the Cool new tools!
Building an application with cool tools that you don't understand
Trusting the important people in your life
Trusting the entire internet to behave
Trust
(but verify)
Security Through Obscurity
Nope, Security via Obscurity is a bad idea
Doing a security review - pen testing, etc.
Having the same person who built the app do the pen testing
OWASP
OWASP
- Non-profit group
- Naming borrowed
- Checkout their recommendations
Injection
SQL Injection
- #1 issue on the web
"SELECT * FROM accounts WHERE custID='" + params.id +"'"
http://example.com/app/accountView?id=' or '1'='1
http://xkcd.com/327/
Preventing SQL injection
Write a method to escape ‘ characters with \’
Use parameterized SQL groovy.sql.Sql
HQL Injection
Similar, different syntax.
String hql = """from AccountHolder
where username = '$username'
and password = '$password'"""
def row = AccountTransaction.executeQuery(hql)
HQL injected
admin' AND substring(password,0,1) == char(64) AND '1' = '1
HQL Injection
use parameterized HQL
Using String concatenation
Using prepared statements
Or better tested sanitization tools
Databinding injection
Databinding Injection
Grails 1.3.7 (pre 1.3.8)
class MyDomainObject {
def SpringSecurityService
...
}
Association Injection
Updating associations that don't belong to that user
Command Injection
“cp img.png ./archive/$filename”.execute()
Log Injection
Extra lines in log files that look real!!
log.info “user benign said ${message}”
http://example.com/thing/action?message=[ERROR] Admin password has expired!! OH CRAP HELP
Transactional Completeness
Transfer example
def transfer(Transfer tfr) {
Deposit d = new Deposit(amount: tfr.amt)
d.save()
Withdrawal w = new Withdrawal(amount: tfr.amt, description: tfr.desc)
w.save()
}
Broken Authentication and Session management
Asking for Credentials to log in
Storing their credentials in clear text
Session Fixation
http://example.com/sale/saleitems;jsessionid=2P0OC2JDPXM0OQSNDLPSKHCJUN2JV?dest=Hawaii
Account Management flow
- Unencrypted transports
- Account signup
- Forgot password
- Password hint exposure
- Insecure SSO
Account Exposure
Cannot find user
vs
Wrong password for user
Poor signup
Overwriting existing account credentials.
Complex Passwords
Password complexity that limits entropy
xkcd.com/936/
XSS
User generated content
Exploits delivered by un-sanitized/unencoded content.
reviewText = """Excellent Product</div>
<iframe src="myadnetwork.com/pwnage.html"/>
<h1>Injected DOM</h1>
<div class='review'>Good work"""
view.gsp (codec = none)
<div class='review'>${reviewText}</div>
DOM Injection
DOM Injection
- Default codec = HTML now
- Careful when doing your own TagLibs
- Anti Samy
Javascript Injection
Via DOM injection of a <script> tag or eval
Vulnerable JS calls
Direct execution
-
eval()
-
window.execScript()/function()/setInterval()/setTimeout()
-
script.src(), iframe.src()
Direct Execution
- document.write(), document.writeln()
- elem.innerHTML = danger
- elem.outerHTML = danger
- elem.setAttribute(“dangerous attribute”, danger)
XSS Bounty
- Cookies in some browsers
- LocalStorage
- Reverse JavaScript Shells
- Stacked
- More..
Insecure Direct Object References
Easy to develop Conventions
Guessable URLs via Exposed Database IDs
Insecure Data
Just change the URL..
https://example.com/account/123
https://example.com/account/999
Secured objects
-
Filters
-
ACL
-
Permissions
Trust but verify!
Secured associations
Ensure the new data is 'owned' by the same party before updating
Ownership level checking Authorization
Security Misconfiguration
DB Console with default Password
...for example
Capturing stacktraces
Exposing Stacktraces to the public
Stacktraces
Indicate framework, versions, package structure and code flow.
SSL Misconfiguration
missing configurations in prod
Sensitive Data Exposure
Requiring your users to authenticate
Allowing Authentication over unsecure channels
Man In The Middle
MiTM
socat -v tcp-listen:8080,fork tcp:localhost:80
Weak Crypto
Short hash
Poor salting
Functional Level access control
Requiring Authentication
Not Checking the specific Authorization for functions
Hidden functionality
- Not showing the links doesn't mean it is protected
- Assuming a user is logged in doesn't mean they should have access to everything
CSRF
Example
<img
src="http://example.com/app/transferFunds?amount=1500&destinationAccount=attackersAcct#"
width="0" height="0" />
Unprotected Actions
URL Mappings
allowedMethods
Unvalidated Redirects and Forwards
Using Components with Known Vulnerabilites
Need I say more?
Heartbleed
http://xkcd.com/1354/
Trusting user input
goto fail
Apple SSL issue
OSX/iOS
Microsoft SSL/TLS vulnerabilities
FIN
Securing your Grails app-2gx-2014
By Colin Harrington
Securing your Grails app-2gx-2014
- 2,866