Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Writing Secure PHP Applications

Writing Secure PHP Applications

Given at the August 2013 San Francisco PHP Meetup (@Mashery)

Chris Cornutt

August 21, 2013
Tweet

More Decks by Chris Cornutt

Other Decks in Technology

Transcript

  1. Hi, I’m Chris Mashery Development Manager, Dallas Security Advocate PHPDeveloper.org

    @enygma ...and other stuff 2 Wednesday, August 21, 2013
  2. SQL injection is ten years old. XSS is eleven years

    old. why are they still a problem? 4 Wednesday, August 21, 2013
  3. Input validation <?php /* Using built-in */ is_numeric(‘1234’); // true

    ctype_digit(‘1234’); // false filter_var(‘invalid.email.com’, FILTER_VALID_EMAIL); // false /* Using 3rd party */ use Respect\Validation\Validator as v; $validator = v::alnum->noWhitespace->length(1,15); var_dump($validator->validate(‘thisisatest’); // true ?> https://github.com/Respect/Validation 24 Wednesday, August 21, 2013
  4. Output escaping <?php /* Using built-in */ htmlspcialchars(‘<script>...</script>’); htmlspecialchars(‘’, ENT_QUOTES,

    ‘UTF-8’); // UTF-7 filter_var(‘invalid.email.com’, FILTER_VALID_EMAIL); // false /* Using 3rd party */ use Zend\Escaper\Escaper; $twig->render(‘...’); // escapes by default, but... ?> Don’t forget the context...especially if there’s multiple! 25 Wednesday, August 21, 2013
  5. Uses HTTP-level compression Reflect user input in body Reflect a

    secret (CSRF) 29 Wednesday, August 21, 2013
  6. Return fast <?php /* Bad practice */ function foo($bar) {

    if ($bar == true) { /* Lots of code here... */ } else { return false; } } //----------------------------------- /* Good practice */ function foo($bar) { if ($bar !== true) { return false; } /* Lots of code here... */ } ?> 30 Wednesday, August 21, 2013
  7. Password hashing <?php /* in PHP 5.5+ */ $hash =

    password_hash($password, PASSWORD_BCRYPT, [‘cost’ => 12]); /* Prior to PHP 5.5+ */ $lib = new \PasswordLib\PasswordLib(); $hash = $lib->createPasswordHash($input); \phpSec\Crypt\Hash::$_method = \phpSec\Crypt\Hash::BCRYPT; $hash = \phpSec\Crypt\Hash::create($input); $bcrypt = new \Zend\Crypt\Password\Bcrypt(); $hash = $bcrypt->create($input); ?> https://github.com/icrmaxell/password_compat 31 Wednesday, August 21, 2013
  8. Encrypted sessions <?php /* Set custom session handler */ session_set_save_handler(

    ‘open’, ‘close’, ‘read’, ‘write’, ‘destroy’, ‘gc’ ); /* Using the handler interface */ class CustomSessionHandler extends SessionHandlerInterface { /* Code goes here */ } $handler = new CustomSessionHandler(); session_set_save_handler($handler, true); ?> https://github.com/enygma/shieldframework/blob/master/Shield/Session.php 32 Wednesday, August 21, 2013
  9. Least privilege <?php /* “Fail fast” for user handling */

    function checkAccess($user, $resource) { if (!$user->allowed($resource) { return false; } /* Other permission checking here */ } /* “Fail least” for user handling */ function checkAccess($user, $resource) { if ($user == null) { return false; } if ($resource == null) { return false; } /* Other permission checking here */ } ?> 33 Wednesday, August 21, 2013
  10. Fail securely <?php /* Custom error handler */ set_error_handler(function($num, $str,

    $file, $line) { echo ‘ERROR: [‘.$num.’] ‘.$str; }); /* Custom exception handler */ set_exception_handler(function($exception) { echo ‘Uncaught exception: ‘.$exception->getMessage(); }); ?> 34 Wednesday, August 21, 2013
  11. Secure Coding Standard Handling auth* Filtering practices/tools Proper configurations Trust

    boundaries Customer data handling 40 Wednesday, August 21, 2013
  12. Secure Code Reviews Set objectives & limit Use questions related

    to your app Review incrementally Review for security only Reflect common issues in coding standards 42 Wednesday, August 21, 2013