Security 202 - Are you sure your site is secure?
Transcript of Security 202 - Are you sure your site is secure?
Are You Sure Your Site Is Secure?
Security 202
Confoo 2011 Edition
By Arne Blankerts, thePHP.cc
What is this talk about?
Myths in web security Broken configurations Typical implementation
issues
Session data
“I can always trust my session datasince I know what I did store”
Session data
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
[theseer@rikka ~] $ grep "session.save_path" /etc/php.ini | grep -v ";"
session.save_path = "/var/lib/php/session"
Session hijacking
“To protect my users from session hijacking, I did implement a
validation check”
Session hijacking
01 <?php02 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 }
session.php
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
Cross Site Request Forgery
“I have an anti CSRF token in my forms – So I'm well protected”
CSRF
01 <?php0203 session_start();04 $_SESSION['CSRF']=md5(time());0506 //...
csrftoken.php
validate.php01 <?php0203 session_start();04 if ($_SESSION['CSRF']==$_GET['CSRF']) {05 // ...06 }
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?
CAPTCHA
“I'm using a captcha to protect my forms from abuse – So I'm save.”
CAPTCHA
Conceptual Problems Distortion often unreadable Not the least bit accessible
Breaking can be “crowd sourced”
Implementation issues
CAPTCHA
captcha.php
validation.php
01 <?php02 session_start();03 require 'captchaHelper.php';0405 $code = generateCaptchaCode();06 $_SESSION['CAPTCHA'] = $code;0708 header('Content-type: image/jpeg');09 echo createCaptchaImage($code);
01 <?php02 session_start();0304 if ($_SESSION['CAPTCHA'] != $_REQUEST['code']) {05 die('Captcha value wrong');06 }07 echo 'Welcome!';
Prepared Statements
“I'm using prepared statementsso I'm protected from sql injections”
Prepared Statements
01 <?php0203 $db = new PDO(....);04 $query = $db->prepare('SELECT ... WHERE NAME=:name');05 $query->bindParam(':name', $_GET['name']);0607 //...
Prepared Statements
What about fieldnames? Variable table names? Do you sort your results? Any need for limits?
Still use ext/mysql? Sprintf based implementations?
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
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.”
Password storage
01 <?php0203 $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']));0910 //...
Most favorite passwords
123456 12345 123456789 Password iloveyou princess rockyou 1234567 12345678
Abc123 Qwertz / Qwerty Dragon Sexgod Football 1234 Pussy Letmein admin
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
Validation
“I know using blacklists is pointless. That's why I use regular expressions to
check for valid chars in a string”
Validation
01 <?php 0203 $name = isset($_GET['name']) ? $_GET['name'] : 'Anonymous User';0405 if (ereg("^[a-zA-Z0-9 +-]*$", $name)) {06 echo "Welcome, $name";07 } else {08 echo "Sorry, that name contains invalid chars";09 }1011 ?>
Clickjacking
“To make sure my site cannot be a victim of clickjacking, I have a Javascript to Break out from
frames or iframes”
Clickjacking
01 <script type=”text/javascript”>02 if (top != self) { top.location.replace(self.location.href); }03 </script>
Old style frame busting code
Clickjacking
01 <script type=”text/javascript”>02 if (top != self) { top.location.replace(self.location.href); }03 </script>
Old style frame busting code
Frame buster busting code01 <script type=”text/javascript”>02 var prevent_bust = 0 03 window.onbeforeunload = function() { prevent_bust++ } 04 setInterval(function() { 05 if (prevent_bust > 0) {06 prevent_bust -= 2 07 window.top.location = 'http://attacker/204.php'; 08 } 09 }, 1); 10 </script>
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
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
Q & A
Congrats!
Contact
Slides will be available
http://talks.thephp.cc
Please rate this talk
http://joind.in/talk/view/2785
Contact options
Email: [email protected] / [email protected]
Follow us on twitter:
@arneblankerts / @thePHPcc