Php My Sql Security 2007


Published on

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Php My Sql Security 2007

  1. 1. PHP and MySQL Web App Security Laura Thomson (
  2. 2. Why is web application security important?
  3. 3. Overview <ul><li>What do I mean by security? </li></ul><ul><ul><li>Specifically security of web apps </li></ul></ul><ul><ul><li>Not how to secure your install </li></ul></ul><ul><ul><li>Not the security of MySQL or PHP </li></ul></ul><ul><ul><li>Programmers’ perspective </li></ul></ul><ul><li>Why is this important? </li></ul><ul><li>Basic principles </li></ul><ul><li>Common attacks and how to defend against them </li></ul><ul><li>Big picture prevention </li></ul><ul><li>Resources </li></ul>
  4. 4. Rationale <ul><li>Before the last couple of years nobody thought about this stuff, like many web related security issues. Lots of programmers drift along blissfully unaware of what can go wrong until something bad happens </li></ul><ul><li>Some well known recent problems with popular web apps (large install base) and well known sites </li></ul><ul><li>This talk: </li></ul><ul><ul><li>Learn the basics (mostly applicable regardless of implementation language) </li></ul></ul><ul><ul><li>Motivate you to learn more </li></ul></ul><ul><ul><li>Far, far too much to cover in the time. This is just an introduction. </li></ul></ul>
  5. 5. Who am I, and why should you listen to me? <ul><li>Principal at OmniTI </li></ul><ul><li>Used MySQL and PHP since last century </li></ul><ul><li>More than a decade of web development experience in a range of languages, using a range of databases </li></ul><ul><li>Long term developer and architect </li></ul><ul><li>What we will cover is not guru level knowledge, but information that every web developer working with MySQL and PHP should know like the back of their hand. </li></ul>
  6. 6. MySQL Security Basics
  7. 7. Basic principles <ul><li>Configure MySQL securely </li></ul><ul><li>Understand the privilege system, and use it appropriately </li></ul><ul><li>Use encryption when needed </li></ul><ul><li>Don’t trust user data (more on this later) </li></ul>
  8. 8. Secure your configuration <ul><li>Simple principles: </li></ul><ul><ul><li>Don’t run mysqld as (Unix) root . Run it as a user created specifically for this purpose, e.g. mysql . Don’t use this account for anything else. (Note that the MySQL root user has nothing to do with Unix users so this doesn’t affect MySQL internally at all.) </li></ul></ul><ul><ul><li>Set permissions on the database directories so that only your mysqld user (e.g. mysql ) can access them. </li></ul></ul><ul><ul><li>Disable symlinks to tables with --skip-symbolic-links . </li></ul></ul><ul><ul><li>Disallow access to port 3306 (or whatever port you have MySQL running on) except from trusted hosts </li></ul></ul>
  9. 9. Accounts and Privileges <ul><li>All MySQL accounts need a password, especially root . (Don’t forget anonymous users, either.) </li></ul><ul><li>Grant users the minimum level of privilege required to do their job. (Principle of Least Privilege) </li></ul><ul><li>Some privileges require special attention: </li></ul><ul><ul><li>Only the root user should have access to the mysql database, which contains privilege information </li></ul></ul><ul><ul><li>Keep FILE, PROCESS, and SUPER for administrative users. FILE enables file creation, PROCESS allows you to see executing processes (including passwords in plaintext), and SUPER can be allowed to e.g. terminate client connections. </li></ul></ul><ul><li>Avoid wildcards in hostnames in the host table. </li></ul><ul><li>Use IPs instead of hostnames in the host table if you don’t trust your DNS </li></ul>
  10. 10. Using encryption <ul><li>Don’t store application passwords in plaintext in the database. (Use one way hashing) </li></ul><ul><li>Require database connections to be via ssh or tunneled through it </li></ul><ul><li>Avoid old MySQL passwords (pre 4.1). (Disable with --secure-auth , and avoid use of --old-passwords .) </li></ul>
  11. 11. PHP Security Basics
  12. 12. Basic principles <ul><li>Consider illegitimate uses of your application </li></ul><ul><li>Educate yourself </li></ul><ul><li>If nothing else, filter all external data </li></ul><ul><ul><li>(From the PHP Security Guide at http:// /projects/guide/ ) </li></ul></ul>
  13. 13. External Data <ul><li>External data is not to be trusted. </li></ul><ul><li>What’s external data? </li></ul><ul><ul><li>Anything from a form </li></ul></ul><ul><ul><li>Anything from $_GET, $_POST, $_REQUEST </li></ul></ul><ul><ul><li>Cookies </li></ul></ul><ul><ul><li>Some server variables (e.g. $_SERVER['SERVER_NAME']) </li></ul></ul><ul><ul><li>Database query results </li></ul></ul><ul><ul><li>Web services data </li></ul></ul><ul><ul><li>Files </li></ul></ul><ul><li>The basic principle is to filter input and escape output </li></ul><ul><li>Filter input using whitelisting where possible </li></ul><ul><li>Escape output according to where it’s going. </li></ul>
  14. 14. Attacks
  15. 15. Attacks <ul><li>Let’s consider some common problems: </li></ul><ul><ul><li>SQL/Command/code Injection </li></ul></ul><ul><ul><li>XSS (Cross Site Scripting) </li></ul></ul><ul><ul><li>Session fixation </li></ul></ul><ul><ul><li>Session hijacking </li></ul></ul><ul><ul><li>Cross site request forgeries (CSRF) </li></ul></ul>
  16. 16. SQL Injection <ul><li>Enter SQL in e.g. form fields in such a way that it is executed on the web app database. </li></ul><ul><li>A variation is command injection, where user data is passed through system() or exec(). </li></ul><ul><li>It’s basically the same attack. </li></ul><ul><li>(Code injection is also a variation, but we’ll talk about that separately) </li></ul>
  17. 17. Example <ul><li>$username = $_POST['username']; </li></ul><ul><li>$password = $_POST['password']; </li></ul><ul><li>$query = &quot;select * from auth where username = '&quot;.$username </li></ul><ul><li>.&quot;' and password = sha1('&quot;.$password.&quot;')&quot;; </li></ul><ul><li>echo $query; </li></ul><ul><li>$db = new mysqli('localhost', 'demo', </li></ul><ul><li>'secret', 'security_demo'); </li></ul><ul><li>$result = $db->query($query); </li></ul><ul><li>if ($result && $result->num_rows) { </li></ul><ul><li>echo &quot;<br />Logged in successfully&quot;; </li></ul><ul><li>} else { </li></ul><ul><li>echo &quot;<br />Login failed&quot;; </li></ul><ul><li>} </li></ul>
  18. 18. Preventing SQL injection <ul><li>Options: </li></ul><ul><ul><li>Filter data using mysql[i]_real_escape_string() </li></ul></ul><ul><ul><li>Manually check each piece of data is the right type </li></ul></ul><ul><ul><li>Use prepared statements and bind variables </li></ul></ul><ul><li>I recommend the use of prepared statements. </li></ul><ul><ul><li>You don’t have to worry about filtering data </li></ul></ul><ul><ul><li>Used as a coding standard, helps to limit problems caused by novice or naïve developers within your organization. </li></ul></ul><ul><ul><li>Gives you other advantages: where queries will be performed multiple times, allows reuse of query plan; uses binary protocol </li></ul></ul><ul><ul><li>Tip: use PDO with prepared statement emulation turned on to leverage MySQL’s query cache </li></ul></ul><ul><li>Note that prepared statements don’t protect you against everything (column/table name injection) </li></ul>
  19. 19. Prepared statements mysqli <ul><li>$query = 'select name, district from city </li></ul><ul><li>where countrycode=?'; </li></ul><ul><li>if ($stmt = $db->prepare($query) ) </li></ul><ul><li>{ </li></ul><ul><li>$countrycode = 'AUS'; </li></ul><ul><li>$stmt->bind_param(&quot;s&quot;, $countrycode); </li></ul><ul><li>$stmt->execute(); </li></ul><ul><li>$stmt->bind_result($name, $district); </li></ul><ul><li>while ($stmt->fetch()) </li></ul><ul><li>{ </li></ul><ul><li>echo $name.', '.$district; </li></ul><ul><li>echo '<br />'; </li></ul><ul><li>} </li></ul><ul><li>$stmt->close(); </li></ul><ul><li>} </li></ul><ul><li>$db->close(); </li></ul>
  20. 20. Prepared statements PDO <ul><li>try { </li></ul><ul><li>$db = new PDO($dsn, $user, $password); </li></ul><ul><li>} catch (PDOException $e) { </li></ul><ul><li>echo 'Connect failed:'. $e->getMessage(); </li></ul><ul><li>} </li></ul><ul><li>$stmt = $db->prepare(“insert into customers (name, address) values (:name, :address)&quot;); </li></ul><ul><li>$stmt->bindParam(‘:name’, $name); </li></ul><ul><li>$stmt->bindParam(‘:address’, $address); </li></ul><ul><li>$stmt->execute(); </li></ul>
  21. 21. XSS <ul><li>XSS = Cross Site Scripting </li></ul><ul><li>An attack by a malicious user where they enter some data to your web application that includes a client side script (generally JavaScript). </li></ul><ul><li>If you output this data to a web page without filtering it, this script will be executed. </li></ul>
  22. 22. Example – part 1 <ul><li><?php </li></ul><ul><li>if (file_exists('comments')) { </li></ul><ul><li>$comments = file_get_contents('comments'); </li></ul><ul><li>} else { </li></ul><ul><li>$comments = ''; </li></ul><ul><li>} </li></ul><ul><li>if (isset($_POST['comment'])) { </li></ul><ul><li>$comments .= '<br />' . $_POST['comment']; </li></ul><ul><li>file_put_contents('comments', $comments); </li></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  23. 23. Example – part 2 <ul><li><form action='xss.php' method='POST'> </li></ul><ul><li>Enter your comments here: <br /> </li></ul><ul><li><textarea name='comment'></textarea> <br /> </li></ul><ul><li><input type='submit' value='Post comment' /> </li></ul><ul><li></form><hr /><br /> </li></ul><ul><li><?php echo $comments; ?> </li></ul>
  24. 24. So what? <ul><li>So it’s JavaScript (or even plain old HTML), I hear you saying, so what? What can I do with that? </li></ul><ul><li>Heaps of badness: </li></ul><ul><ul><li>Annoying popups </li></ul></ul><ul><ul><li>Meta-refresh </li></ul></ul><ul><ul><li>Dubious forms </li></ul></ul><ul><ul><li>Steal cookies (which can then set up a session attack) </li></ul></ul><ul><ul><li>AJAX (XMLHttpRequest) </li></ul></ul>
  25. 25. How do I prevent this? <ul><li>Basically: Filter output to the browser through htmlentities(). </li></ul><ul><li>Not that basic </li></ul><ul><li>See the XSS Cheatsheet: </li></ul><ul><ul><li> </li></ul></ul>
  26. 26. Session fixation <ul><li>Session security works on the basis that a PHPSESSID is hard to guess. If you don’t have to guess it life is much easier. </li></ul><ul><li>PHP can either accept a session id through a cookie or through the URL </li></ul><ul><li>Typically this appears as a phishing attack </li></ul><ul><li>“ Go to this cool site: </li></ul><ul><ul><li>http:// =...” </li></ul></ul><ul><li>Solution: use session_regenerate_id() whenever a user logs in or changes their level of privilege. </li></ul>
  27. 27. Session hijacking <ul><li>Same idea but involves somehow obtaining the session id. </li></ul><ul><li>Refer back to XSS and stealing cookies through JavaScript </li></ul><ul><li>Session ids can be sniffed, or obtained from proxy servers if contained in the URL </li></ul><ul><li>Solutions: </li></ul><ul><ul><li>Regenerate ids </li></ul></ul><ul><ul><li>If using sessions, always use SSL </li></ul></ul><ul><ul><li>Use configuration directive session.use_only_cookies (which will irritate some users) </li></ul></ul>
  28. 28. CSRF <ul><li>CSRF = Cross Site Request Forgeries </li></ul><ul><li>A request for a page that looks as though it was initiated by a site's trusted user, but wasn't (deliberately). Many, many variations. </li></ul><ul><li>Example: </li></ul><ul><li><img src=''> </li></ul><ul><li>Avoid using GET for actions that cause any kind of change to data </li></ul><ul><li>In general, make sure that users come through your forms, and each form submission is matched to an individual form that you send out. </li></ul><ul><li>Generate a one-time token and embed it in the form, save it in the session, and check it on submission. </li></ul><ul><li>Not trivial to protect against </li></ul>
  29. 29. Code injection <ul><li>While this can be grouped with SQL injection and command injection, it’s a serious enough and common enough problem to merit its own slide </li></ul><ul><li>Problem occurs when you accidentally execute arbitrary code, typically via file inclusion </li></ul><ul><li>Poorly written code can allow a remote file to be included and executed as though it were a trusted local file </li></ul><ul><li>Remember that many PHP functions such as require can take an URL or a filename. </li></ul><ul><li>Passing user input as a filename or part of a filename invites users to start filenames with http … </li></ul>
  30. 30. Example: Theme Selector <ul><li><form>Choose Theme: </li></ul><ul><li><select name = theme> </li></ul><ul><li><option value = blue>Blue</option> </li></ul><ul><li><option value = green>Green</option> </li></ul><ul><li><option value = red>Red</option> </li></ul><ul><li></select> </li></ul><ul><li><input type = submit> </li></ul><ul><li></form> </li></ul><ul><li><?php </li></ul><ul><li>if($theme) { </li></ul><ul><li>require($theme.'.txt'); </li></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  31. 31. Prevention <ul><li>Filter user input </li></ul><ul><li>Disable allow_url_fopen and/or allow_url_include setting in php.ini. This disables require/include/fopen of remote files. </li></ul><ul><li>(allow_url_include new in 5.2.0) </li></ul>
  32. 32. Big picture prevention <ul><li>Some basic principles (again): </li></ul><ul><ul><li>Don’t rely on server configuration to protect you (e.g. magic quotes) (always/especially) if you are writing distributable apps </li></ul></ul><ul><ul><li>Design your application with security from the ground up: for example, use a single line of execution that begins with a single point of data cleaning. </li></ul></ul><ul><ul><li>Review your colleagues’ code and have them review yours </li></ul></ul><ul><ul><li>Seek advice from experts where possible (scanning / auditing) </li></ul></ul><ul><ul><li>Educate yourself and your developers and where possible make it easy for your staff to do the right thing. </li></ul></ul><ul><ul><li>Keep your code up to date. Stay on top of patches and advisories. </li></ul></ul>
  33. 33. Resources <ul><li>Open Web Application Security Project </li></ul><ul><li>PHP Security Consortium Guide </li></ul><ul><li>Hardened PHP Patch / Suhosin </li></ul><ul><li> </li></ul><ul><li>Chris Shiflett’s “Essential Security” from O’Reilly (2005) </li></ul>
  34. 34. Final words <ul><li>Slides available for download (after the talk) </li></ul><ul><ul><li> </li></ul></ul><ul><li>These slides are available for use under a Creative Commons license. </li></ul><ul><li>You may use them for any purpose, but must give credit </li></ul><ul><li> </li></ul>
  35. 35. Questions? <ul><li>? </li></ul>