1. Are You Sure Your Site Is Secure?
Security 202
Confoo 2011 Edition
By Arne Blankerts, thePHP.cc
2. What is this talk about?
Myths in web security
Broken configurations
Typical implementation
issues
3. Session data
“I can always trust my session data
since I know what I did store”
4. Session data
[theseer@rikka ~] $ grep "session.save_path" /etc/php.ini | grep -v ";"
session.save_path = "/var/lib/php/session"
Identical for all php instances unless
specifically overwritten
Read and write access from php code
May be crafted in shared hosting
Session-id takeover from vhost to vhost
Session-Content can be modified
Can even lead to code execution
5. Session hijacking
“To protect my users from session
hijacking, I did implement a
validation check”
6. Session hijacking
session.php
01 <?php
02 session_start();
03 $success = true;
04 if (($_SESSION['IP'] != $_SERVER['REMOTE_ADDR'])
05 or ($_SESSION['VIA'] != $_SERVER['HTTP_VIA'])
06 or ($_SESSION['FORWARD'] != $_SERVER['HTTP_X_FORWARDED_FOR'])
07 or ($_SESSION['AGENT'] != $_SERVER['HTTP_USER_AGENT'])) {
08 // ...
09 }
7. Session hijacking – what to do?
Determine if hijacking is a problem
Regenerate id on every request
Doesn't block it but makes it harder to exploit
Fully switch to https for transport
Alternatively use a separate id in ssl context
10. CSRF
Regenerate token for every form?
Do you keep a backlog of tokens?
Do you validate your session?
Session fixation may violate CSRF tokens
What do you base the token on?
11. CAPTCHA
“I'm using a captcha to protect my
forms from abuse – So I'm save.”
12. CAPTCHA
Conceptual Problems
Distortion often unreadable
Not the least bit accessible
Breaking can be “crowd sourced”
Implementation issues
16. Prepared Statements
What about fieldnames?
Variable table names?
Do you sort your results?
Any need for limits?
Still use ext/mysql?
Sprintf based implementations?
17. Drawbacks of sprintf
Manual escaping needed
mysql_escape_string vs. mysql_real_escape_string
PDO::quote() does not work with ODBC
No knowledge of fieldtype
String vs. Integer exploits
PDO::quote vs. mysql(i)_real_escape_string
18. Password storage
“I know storing clear text passwords
is a bad idea. That's why I'm only
storing hashes of passwords to
protect my users.”
19. Password storage
01 <?php
02
03 $db = new PDO(....);
04 $query = $db->prepare(
05 'UPDATE user SET PASSWD=:pwd WHERE UID=:uid'
06 );
07 $query->bindParam(':uid', $_SESSION['uid']);
08 $query->bindParam(':pwd', sha1($_POST['pwd']));
09
10 //...
21. Password storage
Always salt hashes
Prepend and/or append additional values
Stretch your passwords
Re-apply and calculate the hash
400.000 iterations take <1sec on my laptop
Do a quality check on user supplied codes
22. Validation
“I know using blacklists is pointless.
That's why I use regular expressions to
check for valid chars in a string”
27. Clickjacking – what works
JavaScript & CSS
Hide content by use display:none
Switch to visible if frametest succeeds
Use X-FRAME-OPTIONS header
Set to DENY for no iframe embedding
Set to SAMEORIGIN to allow from same host
28. Lessons learned?
Tiny problems add up
Some attacks are only effective if various
vectors get combined
Combinations of attack vectors may render
your solution useless
Security requires a fully secure eco system