Presentation is loading. Please wait.

Presentation is loading. Please wait.

S ECURE P ROGRAMMING NOTES 12 PHP Vulnerabilities 1.

Similar presentations


Presentation on theme: "S ECURE P ROGRAMMING NOTES 12 PHP Vulnerabilities 1."— Presentation transcript:

1 S ECURE P ROGRAMMING NOTES 12 PHP Vulnerabilities 1

2 1. Unvalidated Parameters 2. Broken Access Control 3. Broken Account and Session Management 4. XSS Flaws 5. Buffer Overflows 6. Command Injection Flaws 7. Error Handling Problems 8. Insecure Use of Cryptography 9. Remote Administration Flaws 10. Web and Application Server Misconfiguration 2

3 1.U NVALIDATED P ARAMETERS Most importantly, turn off register_globals. This configuration setting defaults to off in PHP 4.2.0 and later. Access values from URLs, forms, and cookies through the superglobal arrays $_GET, $_POST, and $_COOKIE. Before you use values from the superglobal arrays, validate them to make sure they don’t contain unexpected input. If you know what type of value you are expecting, make sure what you’ve got conforms to an expected format. 3

4 For example, if you’re expecting a US ZIP Code, make sure your value is either five digits or five digits, a hyphen, and four more digits (ZIP+4). Often, regular expressions are the easiest way to validate data: if (preg_match('/^\d{5}(-\d{4})?$/',$_GET['zip'])) { $zip = $_GET['zip']; } else { die('Invalid ZIP Code format.'); } ^ - start of line $ - end of line \d – any digit {5} – exactly 5 of it a? – zero or not of a 4 preg_match — Perform a regular expression match int preg_match ( string $pattern, string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] ) Searches subject for a match to the regular expression given in pattern

5 5

6 If you’re expecting to receive data in a cookie or a hidden form field that you’ve previously sent to a client, make sure it hasn’t been tampered with by sending a hash of the data and a secret word along with the data. Put the hash in a hidden form field (or in the cookie) along with the data. When you receive the data and the hash, re-hash the data and make sure the new hash matches the old one. 6

7 // sending the cookie $secret_word = 'gargamel'; $id = 123745323; $hash = md5($secret_word.$id); setcookie('id',$id.'-'.$hash); // receiving and verifying the cookie list($cookie_id,$cookie_hash) = explode('-',$_COOKIE['id']); if (md5($secret_word.$cookie_id) == $cookie_hash) { $id = $cookie_id; } else { die('Invalid cookie.'); } 7 array explode ( string $delimiter, string $string [, int $limit ] ) Returns an array of strings, each of which is a substring of string formed by splitting it on boundaries formed by the string delimiter. setcookie() defines a cookie to be sent along with the rest of the HTTP headers. Once the cookies have been set, they can be accessed on the next page load with the $_COOKIE or $HTTP_COOKIE_VARS arrays

8 If a user has changed the ID value in the cookie, the hashes won’t match. The success of this method obviously depends on keeping $secret_word secret, so put it in a file that can’t be read by just anybody and change it periodically. (But remember, when you change it, old hashes that might be lying around in cookies will no longer be valid.) 8

9 2.B ROKEN A CCESS C ONTROL Instead of rolling your own access control solution, use PHP Extension and Application Repository (PEAR) modules. Auth does cookie-based authentication for you and Auth_HTTP does browser-based authentication 9

10 The PHP Extension and Application Repository, or PEAR, is a repository (storehouse) of PHP software code. Stig S. Bakken founded the PEAR project in 1999 to promote the re-use of code that performs common functions. The project seeks to provide a structured library of code, maintain a system for distributing code and for managing code packages, and promote a standard coding style How to install an additional Pear package http://www.siteground.com/tutorials/php- mysql/pear_modules.htm PEAR FAQ http://pear.php.net/manual/en/faq.users.php 10

11 "pgsql://test:test@localhost/testdb",// data source name 'table'=>"testable",// your table name 'usernamecol'=>"username", // the table username column 'passwordcol'=>"password",// the table password column 'cryptType'=>"none", // password encryption type in your db ); $a = new Auth_HTTP("DB", $AuthOptions); $a->setRealm('yourrealm'); // realm name $a->setCancelText(' Error 401 '); // error message if authentication fails $a->start(); // starting the authentication process if($a->getAuth()) // checking for authenticated user { echo "Hello $a->username welcome to my secret page"; }; ?> 11 Example: A simple password protected page

12 "pgsql://test:test@localhost/testdb",// data source name 'table'=>"testable", // your table name 'usernamecol'=>"username", // the table username column 'passwordcol'=>"password", // the table password column 'cryptType'=>"md5", // password encryption type in your db 'db_fields'=>"*", // enabling fetch for other db columns ); $a = new Auth_HTTP("DB", $AuthOptions); $a->setRealm('yourrealm'); // realm name $a->setCancelText(' Error 401 '); // error message if authentication fails $a->start(); // starting the authentication process if($a->getAuth()) // checking for authenticated user { echo "Hello $a->username welcome to my secret page "; echo "Your details on file are: "; echo $a->getAuthData('userid'); // retrieving other details from the database row echo $a->getAuthData('telephone'); // in this example the user id, telephone number echo $a->getAuthData('email'); // and email address }; ?> 12 A password protected page with multiple rows fetch and md5 password

13 3.B ROKEN A CCOUNT AND S ESSION M GMT Use PHP’s built-in session management functions for secure, standardized session management. However, be careful how your server is configured to store session information. For example, if session contents are stored as world- readable files in /tmp, then any user that logs into the server can see the contents of all the sessions. Store the sessions in a database or in a part of the file system that only trusted users can access. To prevent network sniffers from scooping up session IDs, session-specific traffic should be sent over SSL. You don’t need to do anything special to PHP when you’re using an SSL connection, but you do need to specially configure your webserver. 13

14 Here is a sample code which can be used to create logged sessions: Code for differentiating Guest and Logged members: <?php session_start();// starting the session if(isset($_SESSION['user'])) { // Code for Logged members $user = $_SESSION['user']; // identifying the user // Information for the user. } else { // Code to show Guests } ?> Code for Logging a User: <?php define("USER", "user"); // username stored for logging define("PASS", "123456"); // password stored // Normal user section - Not logged ------ if(isset($_REQUEST['username']) && isset($_REQUEST['password'])) { // Section for logging process ----------- $user = trim($_REQUEST['username']); $pass = trim($_REQUEST['password']); if($user == USER && $pass == PASS) { // Successful login ------------------ $_SESSION['user'] = USER; // Setting Session header("Location: index.php"); // Redirecting to the logged page. } else { // Wrong username or Password. Show error here. } } ?> 14 User can be logged successfully with username as "user" and password as 123456. session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie. trim — Strip whitespace (or other characters) from the beginning and end of a string " " (ASCII 32 ( 0x20 )), an ordinary space. "\t" (ASCII 9 ( 0x09 )), a tab. "\n" (ASCII 10 ( 0x0A )), a new line (line feed). "\r" (ASCII 13 ( 0x0D )), a carriage return. "\0" (ASCII 0 ( 0x00 )), the NUL - byte. "\x0B" (ASCII 11 ( 0x0B )), a vertical tab.

15 4.C ROSS S ITE S CRIPTING (XSS) Never display any information coming from outside your program without filtering it first. Filter variables before including them in hidden form fields, in query strings, or just plain page output. PHP gives you plenty of tools to filter untrusted data: htmlspecialchars() turns & > " < into their HTML-entity equivalents and can also convert single quotes by passing ENT_QUOTES as a second argument. strtr() filters any characters you’d like. Pass strtr() an array of characters and their replacements. To change ( and ) into their entity equivalents, which is recommended to prevent XSS attacks, do: $safer = strtr($untrusted, array('(' => '(', ')' => ')')); strip_tags() removes HTML and PHP tags from a string. 15

16 <?php $new = htmlspecialchars(" Test ", ENT_QUOTES); echo $new; // <a href='test'>Test</a> ?> <?php //In this form, strtr() does byte-by-byte translation //Therefore, we are assuming a single-byte encoding here: $addr = strtr($addr, "äåö", "aao"); ?> <?php $trans = array("h" => "-", "hello" => "hi", "hi" => "hello"); echo strtr("hi all, I said hello ha ha ha", $trans); ?> <?php $text = ' Test paragraph. Other text '; echo strip_tags($text); echo "\n"; // Allow and echo strip_tags($text, ' '); ?> 16 The translations performed are: '&' (ampersand) becomes '&' '"' (double quote) becomes '"' when ENT_NOQUOTES is not set. "'" (single quote) becomes ''' only when ENT_QUOTES is set. '<' (less than) becomes '<' '>' (greater than) becomes '>' strtr - Translate characters or replace substrings string strtr (string $str, string $from, string $to) string strtr (string $str, array $replace_pairs ) Output: hello all, I said hi -a -a -a strip_tags — Strip HTML and PHP tags from a string Output: Test paragraph. Other text

17 5.B UFFER O VERFLOWS You can’t allocate memory at runtime in PHP and their are no pointers like in C so your PHP code, however sloppy it may be, won’t have any buffer overflows. What you do have to watch out for, however, are buffer overflows in PHP itself (and its extensions.) Subscribe to the php-announce mailing list to keep abreast of patches and new releases. 17

18 6.C OMMAND I NJECTION F LAWS Cross-site scripting flaws happen when you display unfiltered, unescaped malicious content to a user’s browser. Command injection flaws happen when you pass unfiltered, unescaped malicious commands to an external process or database. To prevent command injection flaws, in addition to validating input, always escape user input before passing it to an external process or database. 18

19 If you’re passing user input to a shell (via a command like exec(), system(), or the backtick operator), first, ask yourself if you really need to. Most file operations can be performed with native PHP functions. If you absolutely, positively need to run an external program whose name or arguments come from untrusted input, escape program names with escapeshellcmd() and arguments with escapeshellarg(). 19

20 Before executing an external program or opening an external file, you should also canonicalize its pathname with realpath(). This expands all symbolic links, translates. (current directory).. (parent directory), and removes duplicate directory separators. Once a pathname is canonicalized you can test it to make sure it meets certain criteria, like being beneath the web server document root or in a user’s home directory. If you’re passing user input to a SQL query, escape the input with addslashes() before putting it into the query. If you’re using MySQL, escape strings with mysql_real_escape_string() (or mysql_escape_string() for PHP versions before 4.3.0). If you’re using the PEAR DB database abstraction layer, you can use the DB::quote() method or use a query placeholder like ?, which automatically escapes the value that replaces the placeholder. 20

21 <?php $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password') // Connect OR die(mysql_error()); // Query $query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'", mysql_real_escape_string($user), mysql_real_escape_string($password)); ?> <?php // We didn't check $_POST['password'], it could be anything the user wanted! For example: $_POST['username'] = 'aidan'; $_POST['password'] = "' OR ''='"; // Query database to check if there are any matching users $query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'"; mysql_query($query); // This means the query sent to MySQL would be: echo $query; ?> 21 Example #2 An example SQL Injection Attack The query sent to MySQL: SELECT * FROM users WHERE user='aidan' AND password='' OR ''='' This would allow anyone to log in without a valid password. Example #1 Simple mysql_real_escape_string() example

22 7.E RROR H ANDLING P ROBLEM If users (and attackers) can see the raw error messages returned from PHP, your database, or external programs, they can make educated guesses about how your system is organized and what software you use. These educated guesses make it easier for attackers to break into your system. Error messages shouldn’t contain any descriptive system information. Tell PHP to put error messages in your server’s error log instead of displaying them to a user with these configuration directives: log_errors = On display_errors = Off 22 Example http://my.php.net/manual/en/errorfunc.examples.php

23 23 phpinfo() php.ini display_errors = On log_errors = On

24 8.I NSECURE U SE OF C RYPTOGRAPHY The mcrypt extension provides a standardized interface to many popular cryptographic algorithms. Use mcrypt instead of rolling your own encryption scheme. Also, be careful about where (if anywhere) you store encryption keys. The strongest algorithm in the world is pointless if an attacker can easily obtain a key for decryption. If you need to store keys at all, store them apart from encrypted data. Better yet, don’t store the keys and prompt users to enter them when something needs to be decrypted. (Of course, if you’re prompting a user over the web for sensitive information like an encryption key, that prompt and the user’s reply should be passed over SSL.) 24

25 As of PHP 5.0.0 you will need libmcrypt Version 2.5.6 or greater. http://mcrypt.sourceforge.net/ 25 Encrypt an input value with TripleDES under 2.2.x in ECB mode Encrypt an input value with TripleDES under 2.4.x and higher in ECB mode

26 9. R EMOTE A DMINISTRATION F LAWS When possible, run remote administration tools over an SSL connection to prevent sniffing of passwords and content. If you’ve installed third-party software that has a remote administration component, change the default administrative user names and passwords. Change the default administrative URL as well, if possible. Running administrative tools on a different web server than the public web server that the administrative tool administrates can be a good idea as well. 26

27 10. W EB AND A PPLICATION S ERVER M ISCONFIGURATION Keep on top of PHP patches and security problems by subscribing to the php-announce mailing list. Stay away from the automatic PHP source display handler (AddType application/x-httpd-php-source.phps ), since it lets attackers look at your code. Of the two sample php.ini files distributed with PHP ( php.ini-dist and php.ini-recommended ), use php.ini- recommended as a base for your site configuration. 27


Download ppt "S ECURE P ROGRAMMING NOTES 12 PHP Vulnerabilities 1."

Similar presentations


Ads by Google