Jordi Boggiano | Liip AG
Security, what you MUST know
- Injection >
- Cross-Site Scripting / XSS >
- Broken Auth. and Session Management >
- Insecure Direct Object References >
- Cross-Site Request Forgery / CSRF >
- Misconfiguration >
- Insecure Cryptographic Storage >
- Failure to Restrict URL Access >
- Insufficient Transport Layer Protection >
- Unvalidated Redirects and Forwards >
- (Clickjacking) >
Injection
Escape, escape, escape
SQL is the usual suspect, but also IO, system calls, ..
echo file_get_contents($_GET['file']);
// ?file=../config.php
$pdo->query('SELECT * FROM foo WHERE password="'.$_GET['pwd'].'"');
// ?pwd=food" OR 1=1 --
exec('rm -rf upload/'.$_GET['file']);
// ?file=*; rm -rf /;
- prepared statements or mysql(i)_real_escape_string()
- basename() / realpath()
- shell_escape_args()
- white-lists
Cross-Site Scripting / XSS
Don't trust anyone
<p><?php echo $userContent; ?></p>
<img src="foo.jpg" title="<?php echo $userContent; ?>" />
- HTML5
- htmlspecialchars()
- HTMLPurifier
- Don't even trust admins
Broken Auth. and Session Management
Protect passwords
- Salt passwords
- Never ever store passwords in clear text
- Hash passwords properly (sha256 or above)
Avoid session fixation and brute-force attacks
- session.cookie_httponly = 1
- session.use_only_cookies = 1
- session_regenerate_id()
- session.entropy_length = 32
Insecure Direct Object References
Attackers aren't retards
http://example.org/id=3
http://example.org/id=5
http://example.org/id=X
- Always check the user credentials before allowing access to restricted content
Cross-Site Request Forgery / CSRF
Death from above
<form action="http://twitter.com/submit">
<input type="hidden" name="tweet"
value="I'm in your twitter, spamming all your friends" />
<input type="submit" value="Click me!" />
</form>
<img src="http://facebook.com/account?action=delete" />
- Create one unique token per user at least once per session
- Include/verify it in every sensitive form
<input name="authenticity_token" type="hidden" value="829000ddb69cdf1ffbdd8f2543b79f5e8b27add6" />
Misconfiguration
Maintenance is key
- Update apps/libraries
- Disable unnecessary services
- Watch for yoursite.com/.svn/
- Disable or fix default accounts (admin/admin)
- php.ini settings
Insecure Cryptographic Storage
Encrypt sensitive data
- Use strong encryption algorithms
- Check with a crypto expert
- Change your (strong) encryption key regularly
- Again, salt your passwords
Failure to Restrict URL Access
Links aren't everything
- Make sure you check credentials when you serve a page, picture or anything
Insufficient Transport Layer Protection
«But cables are so ugly..»
- Use SSL
- At least force the password to be sent encrypted
- Ideally any page using the session should have SSL
Unvalidated Redirects and Forwards
Still trusting that user input?
http://example.org/redirect.php?url=http://evample.org
- Don't take user input as a redirection target
- If you must, use a white-list with a look-up table rather than plain URL bits
Clickjacking
Click here to see naked $whateverYouFancy
<iframe src="http://twitter.com/?status=I'm in your tweets again"></iframe>
- Set the X-Frame-Options header, DENY or SAMEORIGIN
- Works in IE8, Opera10.5, Safari4, Chrome4 and Firefox3.7
- JS frame-busting solutions are available but they're unreliable
Goals for a more secure web
- Educate every web dev about security
- Design securely from the start
- Make security a part of testing/reviews
- Encourage paranoid delusions, minor leaks can lead to disasters