Best PHP Practices and Security Considerations - PHP
PHP GET and POST are predefined global and associated array variables used for retrieving user submitted information passed using HTTP GET and HTTP POST methods. They are mostly used with PHP web form applications where you need to interact with your user input. This tutorial is a complete guide to using PHP GET and POST functions with illustrative examples and security considerations.
Below are some of the best practices for implementing $_POST and $_GET:
1.) Do not use $_GET when submitting sensitive information to the web server. This includes usernames and passwords. However sensitive information sent using $_POST is still not perfectly safe from eavesdropping if it travels in an unsecured channel. This is where you will need to use SSL (https) in sensitive pages such as login forms. This will encrypt the traffic sent using $_POST.
2.) For most web form applications that require users to submit text information. $_POST method is the most reliable method because it allows users to submit large amounts of information and will not complicate the resulting URL.
3.) Combine the web form and processing script as one PHP file, this is easier to maintain and efficient. In a basic example the web form (e.g. basicpost.php or basicget.php) and the processing script (processor.php) are separated. You can use the code below (e.g. you named it as “combined.php”):
<html> <head> <title>Combined form and processor using PHP $_POST</title> </head> <body> <?php if (!isset($_POST['yourname'])) { //Web form is not submitted, show the HTML Form ?> <form action="<?php echo $SERVER['PHP_SELF']; ?>" method="post"> Please enter your name: <input name="yourname" type="text" /> <input type="submit" name="submit" value="Submit this form"> </form> <?php } else { //Form submitted //Process the form, retrieve name from the web form which is submitted using HTTP POST Method $name= $_POST['yourname']; //Output the name back to the browser echo "Your name is $name."; } ?> </body> </html>
Warning: The above code does not contain any validation measures. Do not use it for practical applications.
5.) Validate ALL external/user inputs when using $_GET or $_POST. This prevents your site from being hacked using cross site scripting, MySQL injection and other hacking methods. Read the next section.
Securing and Sanitizing $_POST / $_GET input
It is recommended that even if you are a beginner at using $_POST and $_GET, you need to put strong importance on security. Below is a sample code that sanitizes $_POST and $_GET input with the following assumptions:
You are only accepting plain text/string input.
You are inserting strings to a MySQL database.
You are not accepting HTML input and PHP input from your users.
<head> <title>PHP Form template using sanitized $_POST</title> </head> <body> <?php if (!isset($_POST['yourname'])) { ?> <form action="<?php echo $SERVER['PHP_SELF']; ?>" method="post"> Please enter your name: <input name="yourname" type="text" /> <input type="submit" name="submit" value="Submit this form"> </form> <?php } else { //Form submitted //Connect to MySQL database include 'databaseconnect.php';
//Define the sanitize inputs function
function sanitizeinputs($input) { //Retrieve values from HTTP POST and remove any possibility of user injecting HTML and PHP tags as input using strip tags function
$input= strip_tags(trim($input));
//Convert newline characters to <br /> to any possibility of cross site scripting using newline characters
$input = nl2br($input);
//Entity quote remaining dangerous characters
$input= htmlspecialchars($input);
//Sanitize in preparation to any database queries $input = mysql_real_escape_string($input); return $input; } $name= sanitizeinputs($_POST['yourname']); echo "Your name is $name."; } ?> </body> </html>
Notes:
1.) For $_GET, simply replace the above $_POST with $_GET and the validation is fairly similar. You might also need to check if the form originates from your own website and not from other malicious sites (preventing cross site request forgery). You can do this using a combination of nonce/token key as well as sessions. Supposing you need to check that the moderator is deleting a post that originates from your own site.
//Check if post_id is not empty if(!empty($_POST['post_id']) {
//Post_id is not empty, check if the user is the moderator if( !user->is_a_moderator )
//Not a moderator, end the script execution die;
//Check if token is empty OR token is not equal to the correct token defined in the session variable. If the form originates from outside your site, it cannot obtain correct token. if( empty($_POST['token']) || $_POST['token'] != $_SESSION['token']) die;
// All validation is OK, proceed to delete the post. delete_post(intval($_POST['post_id']));
// Unset the token, so that it cannot be used again. unset($_SESSION['token']); }
//Generate token $token = md5(uniqid(rand(), true)); $_SESSION['token'] = $token; ?> //Show web form pass token in hidden field <form method="post"> <p>Post ID to delete:</p> <p><input type="text" name="post_id" /></p> <input type="hidden" name="token" value="<?php echo $token; ?>" /> </form>
2.) For $_GET retrieving id from the URL (very common), one way to sanitize against MySQL injection is using intval function:
<?php
$query_id= $_GET['id']; $id=intval($query_id);
mysql_query('SELECT * FROM members WHERE id='.$id);
?>
So a malicious input of 1 or 1=1 will become 1 only.
Final remarks: There is no general validation/sanitization code (one sanitizing function fits all). Each PHP web application is unique should have its own unique set of validation/sanitizing procedures. For example if a PHP variable is used to execute a command shell then it must be sanitized with escapeshellarg() function to make it safe if the variable value originates from a user-input.