Programming PHP
Kindle Highlights
The best protection against SQL injection is the use of bound parameters.
Essential PHP Security (O’Reilly) by Chris Shiflett and its companion website
Whenever you construct a filename, check the components with basename() and realpath().
Whenever you construct a filename from a user-supplied component, check the components with basename() and realpath().
In order to prevent XSS, you simply need to properly escape your output for the output context: $html = array( ‘username’ => htmlentities($_POST[‘username’], ENT_QUOTES, “UTF-8”), );
Because bound parameters ensure that the data never enters a context where it can be considered anything but data (i.e., it’s never misinterpreted), no escaping of the username and password is necessary.
A RESTful web service is a loose description of web APIs implemented using HTTP and the principles of Representational State Transfer (REST). It refers to a collection of resources, along with basic operations a client can perform on those resources through the API.
Safeguarding your applications against SQL injection is primarily accomplished by escaping output: $mysql = array(); $hash = hash($_POST[‘password’]); $mysql[‘username’] = mysql_real_escape_string($clean[‘username’]); $sql = “SELECT count(*) FROM users WHERE username = ‘{$mysql[‘username’]}’ AND password = ‘{$hash}’”; $result = mysql_query($sql);
Data Encryption Concerns One last topic to cover is encrypting data that you want to ensure is not viewable in its native form. This mostly applies to website passwords, but there are other examples, such as Social Security numbers (Social Insurance numbers in Canada), credit card numbers, and bank account numbers. Check out the discussion on the FAQ page of the PHP website to find the best approach for your specific data encryption needs.
If the user passes a theme parameter of https://www.example.com/badcode.inc and your variables_order includes GET or POST, your PHP script will happily load and run the remote code. Never use parameters as filenames like this. There are several solutions to the problem of checking filenames. You can disable remote file access, check filenames with realpath() and basename() (as described next), and use the open_basedir option to restrict filesystem access outside your site’s document root.
If you’re using Apache, you can use the Apache benchmarking utility, ab, to do high-level performance testing. To use it, run: $ /usr/local/apache/bin/ab -c 10 -n 1000 http://localhost/info.php This command tests the speed of the PHP script info.php 1,000 times, with 10 concurrent requests running at any given time. The benchmarking tool returns various information about the test, including the slowest, fastest, and average load times. You can compare those values to a static HTML page to see how quickly your script performs.
Beware of filling your filesystem Another trap is the size of uploaded files. Although you can tell the browser the maximum size of file to upload, this is only a recommendation and does not ensure your script won’t be handed a file of a larger size. Attackers can perform a denial-of-service attack by sending files large enough to fill up your server’s filesystem. Set the post_max_size configuration option in php.ini to the maximum size (in bytes) that you want: post_max_size = 1024768; // one megabyte PHP will ignore requests with data payloads larger than this size. The default 10 MB is probably larger than most sites require.
Distrust browser-supplied filenames Be careful using the filename sent by the browser. If possible, do not use it as the name of the file on your filesystem. It’s easy to make the browser send a file identified as /etc/passwd or /home/kevin/.forward. You can use the browser-supplied name for all user interaction, but generate a unique name yourself to actually call the file. For example: $browserName = $_FILES[‘image’][’name’]; $tempName = $FILES[‘image’][’tmp_name’]; echo “Thanks for sending me {$browserName}.”; $counter++; // persistent variable $filename = “image{$counter}”; if (is_uploaded_file($tempName)) { move_uploaded_file($tempName, “/web/images/{$filename}”); } else { die(“There was a problem processing the file.”); } Beware