Friday, November 8, 2013

PHP Form Validation And Security Concerns


-----

Think SECURITY when processing PHP forms!
Proper validation of form data is important to protect your form from hackers and spammers!


1) HTML FORM
2) HTML code for the form:
3) FORM SUBMISSION
4) Big Note on PHP Form Security
5) How To Avoid $_SERVER["PHP_SELF"] Exploits?
6) Validate Form Data With PHP

1) HTML FORM

1.1) The HTML form we will be working here contains various input fields: required and optional text fields, radio buttons, and a submit button:
1.2) The validation rules for the form above are as follows:
Field
Validation Rules
Name
Required. + Must only contain letters and whitespace
E-mail
Required. + Must contain a valid email address (with @ and .)
Website
Optional. If present, it must contain a valid URL
Comment
Optional. Multi-line input field (textarea)
Gender
Required. Must select one

2) HTML code for the form:

2.1) Text Fields
The name, email, and website fields are text input elements, and the comment field is a textarea. The HTML code looks like this:
Name: <input type="text" name="name">
E-mail: <input type="text" name="email">
Website: <input type="text" name="website">
Comment: <textarea name="comment" rows="5" cols="40"></textarea>
2.2) Radio Buttons
The gender fields are radio buttons and the HTML code looks like this:
Gender:
<input type="radio" name="gender" value="female">Female
<input type="radio" name="gender" value="male">Male
2.3) The Form Element
The HTML code of the form looks like this:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

3) FORM SUBMISSION

3.1) When the form is submitted, the form data is sent with method="post".
What is the $_SERVER["PHP_SELF"] variable?

The $_SERVER["PHP_SELF"] is a super global variable that returns the filename of the currently executing script.
3.2) So, the $_SERVER["PHP_SELF"] sends the submitted form data to the page itself, instead of jumping to a different page. This way, the user will get error messages on the same page as the form.
What is the htmlspecialchars() function?

The htmlspecialchars() function 
converts special characters to HTML entities. This means that it will replace HTML characters like < and > with &lt; and &gt;. This prevents attackers from exploiting the code by injecting HTML or Javascript code (Cross-site Scripting attacks) in forms.

4) Big Note on PHP Form Security

4.1) The $_SERVER["PHP_SELF"] variable can be used by hackers!
4.2) If PHP_SELF is used in your page then a user can enter a slash (/) and then some Cross Site Scripting (XSS) commands to execute.
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications. XSS enables attackers to inject client-side script into Web pages viewed by other users.
4.3) Assume we have the following form in a page named "test_form.php":
<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">
4.4) Now, if a user enters the normal URL in the address bar like "http://www.example.com/test_form.php", the above code will be translated to:
<form method="post" action="test_form.php">
So far, so good.
4.5) However, consider that a user enters the following URL in the address bar:
http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E
4.6) In this case, the above code will be translated to:
<form method="post" action="test_form.php"/><script>alert('hacked')</script>
4.7) This code adds a script tag and an alert command. And when the page loads, the JavaScript code will be executed (the user will see an alert box). This is just a simple and harmless example how the PHP_SELF variable can be exploited.
4.8) Be aware of that any JavaScript code can be added inside the <script> tag! A hacker can redirect the user to a file on another server, and that file can hold malicious code that can alter the global variables or submit the form to another address to save the user data, for example.

5) How To Avoid $_SERVER["PHP_SELF"] Exploits?

5.1) $_SERVER["PHP_SELF"] exploits can be avoided by using the htmlspecialchars() function.
5.2) The form code should look like this:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
5.3) The htmlspecialchars() function converts special characters to HTML entities. Now if the user tries to exploit the PHP_SELF variable, it will result in the following output:
<form method="post" action="test_form.php/&quot;&gt;&lt;script&gt;alert('hacked')&lt;/script&gt;">
The exploit attempt fails, and no harm is done!

6) Validate Form Data With PHP

6.1) The first thing we will do is to pass all variables through PHP's htmlspecialchars() function.
6.2) When we use the htmlspecialchars() function; then if a user tries to submit the following in a text field:
<script>location.href('http://www.hacked.com')</script>
6.3) this would not be executed, because it would be saved as HTML escaped code, like this:
&lt;script&gt;location.href('http://www.hacked.com')&lt;/script&gt;
6.4) The code is now safe to be displayed on a page or inside an e-mail.
6.5) We will also do two more things when the user submits the form:
  1. Strip unnecessary characters (extra space, tab, newline) from the user input data (with the PHP trim() function)
  2. Remove backslashes (\) from the user input data (with the PHP stripslashes() function)
6.6) The next step is to create a function that will do all the checking for us (which is much more convenient than writing the same code over and over again).
6.7) We will name the function test_input().
6.8) Now, we can check each $_POST variable with the test_input() function, and the script look like this:
<?php
// define variables and set to empty values
$name = $email = $gender = $comment = $website = "";
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
  $name = test_input($_POST["name"]);
  $email = test_input($_POST["email"]);
  $website = test_input($_POST["website"]);
  $comment = test_input($_POST["comment"]);
  $gender = test_input($_POST["gender"]);
}
function test_input($data)
{
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
}
?>
6.9) Notice that at the start of the script, we check whether the form has been submitted using $_SERVER["REQUEST_METHOD"]. If the REQUEST_METHOD is POST, then the form has been submitted - and it should be validated. If it has not been submitted, skip the validation and display a blank form.
6.10) However, in the example above, all input fields are optional. The script works fine even if the user do not enter any data.


PHP Form Handling: Get and Post Issues


-----


1) PHP - A Simple HTML Form
2) What is missing here?
3) GET vs. POST
4) When to use GET?
5) When to use POST?

1) PHP - A Simple HTML Form

1.1) The example below displays a simple HTML form with two input fields and a submit button:
<html>
<body>
<form action="welcome.php" method="post">
Name: <input type="text" name="name"><br>
E-mail: <input type="text" name="email"><br>
<input type="submit">
</form>
</body>
</html>
1.2) When the user fills out the form above and clicks the submit button, the form data is sent for processing to a PHP file named "welcome.php". The form data is sent with the HTTP POST method.
1.3) To display the submitted data you could simply echo all the variables. The "welcome.php" looks like this:
<html>
<body>
Welcome <?php echo $_POST["name"]; ?><br>
Your email address is: <?php echo $_POST["email"]; ?>
</body>
</html>
1.4) Outcome:
1.5) The same result could also be achieved using the HTTP GET method:
<html>
<body>
<form action="welcome_get.php" method="get">
Name: <input type="text" name="name"><br>
E-mail: <input type="text" name="email"><br>
<input type="submit">
</form>
</body>
</html>
1.6) and "welcome_get.php" looks like this:
<html>
<body>
Welcome <?php echo $_GET["name"]; ?><br>
Your email address is: <?php echo $_GET["email"]; ?>
</body>
</html>
1.7) Outcome:

2) What is missing here?

2.1) The code above is quite simple.
2.2) However, the most important thing is missing. You need to validate form data to protect your script from malicious code.

3) GET vs. POST

3.1) Both GET and POST create an array (e.g. array( key => value, key2 => value2, key3 => value3, ...)). This array holds key/value pairs, where keys are the names of the form controls and values are the input data from the user.
3.2) Both GET and POST are treated as $_GET and $_POST. These are superglobals, which means that they are always accessible, regardless of scope - and you can access them from any function, class or file without having to do anything special.
3.3) $_GET is an array of variables passed to the current script via the URL parameters.
3.4) $_POST is an array of variables passed to the current script via the HTTP POST method.

4) When to use GET?

4.1) Information sent from a form with the GET method is visible to everyone (all variable names and values are displayed in the URL). GET also has limits on the amount of information to send. The limitation is about 2000 characters. However, because the variables are displayed in the URL, it is possible to bookmark the page. This can be useful in some cases.
4.2) GET may be used for sending non-sensitive data.
4.3) Note: GET should NEVER be used for sending passwords or other sensitive information!

5) When to use POST?

5.1) Information sent from a form with the POST method is invisible to others (all names/values are embedded within the body of the HTTP request) and has no limits on the amount of information to send.
5.2) Moreover POST supports advanced functionality such as support for multi-part binary input while uploading files to server.
5.3) However, because the variables are not displayed in the URL, it is not possible to bookmark the page.

PHP Global Variables – Superglobals


-----
1) What is Superglobal Variables?
2) PHP $GLOBAL
3) PHP $_SERVER
4) PHP $_REQUEST
5) PHP $_POST

1) What is Superglobal Variables?

1.1) Superglobals were introduced in PHP 4.1.0, and are built-in variables that are always available in all scopes.
1.2) They are always accessible, regardless of scope - and you can access them from any function, class or file without having to do anything special.
1.3) The PHP superglobal variables are:
  • $GLOBALS
  • $_SERVER
  • $_REQUEST
  • $_POST
  • $_GET
  • $_FILES
  • $_ENV
  • $_COOKIE
  • $_SESSION

2) PHP $GLOBAL

2.1) $GLOBAL is a PHP super global variable which is used to access global variables from anywhere in the PHP script (also from within functions or methods).
2.2) PHP stores all global variables in an array called $GLOBALS[index]. The index holds the name of the variable.
2.3) The example below shows how to use the super global variable $GLOBAL:
<?php
$x = 75;
$y = 25;

function addition()
{
$GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y'];
}

addition();
echo $z;
?>
2.4) In the example above, since z is a variable present within the $GLOBALS array, it is also accessible form outside the function!

3) PHP $_SERVER

3.1) $_SERVER is a PHP super global variable which holds information about headers, paths, and script locations.
3.2) The example below shows how to use some of the elements in $_SERVER:
<?php
echo $_SERVER['PHP_SELF'];
echo "<br>";
echo $_SERVER['SERVER_NAME'];
echo "<br>";
echo $_SERVER['HTTP_HOST'];
echo "<br>";
echo $_SERVER['HTTP_REFERER'];
echo "<br>";
echo $_SERVER['HTTP_USER_AGENT'];
echo "<br>";
echo $_SERVER['SCRIPT_NAME'];
?>
3.3) The following table lists the most important elements that can go inside $_SERVER:
Element/Code
Description
$_SERVER['PHP_SELF']
Returns the filename of the currently executing script
$_SERVER['GATEWAY_INTERFACE']
Returns the version of the Common Gateway Interface (CGI) the server is using
$_SERVER['SERVER_ADDR']
Returns the IP address of the host server
$_SERVER['SERVER_NAME']
Returns the name of the host server (such as www.w3schools.com)
$_SERVER['SERVER_SOFTWARE']
Returns the server identification string (such as Apache/2.2.24)
$_SERVER['SERVER_PROTOCOL']
Returns the name and revision of the information protocol (such as HTTP/1.1)
$_SERVER['REQUEST_METHOD']
Returns the request method used to access the page (such as POST)
$_SERVER['REQUEST_TIME']
Returns the timestamp of the start of the request (such as 1377687496)
$_SERVER['QUERY_STRING']
Returns the query string if the page is accessed via a query string
$_SERVER['HTTP_ACCEPT']
Returns the Accept header from the current request
$_SERVER['HTTP_ACCEPT_CHARSET']
Returns the Accept_Charset header from the current request (such as utf-8,ISO-8859-1)
$_SERVER['HTTP_HOST']
Returns the Host header from the current request
$_SERVER['HTTP_REFERER']
Returns the complete URL of the current page (not reliable because not all user-agents support it)
$_SERVER['HTTPS']
Is the script queried through a secure HTTP protocol
$_SERVER['REMOTE_ADDR']
Returns the IP address from where the user is viewing the current page
$_SERVER['REMOTE_HOST']
Returns the Host name from where the user is viewing the current page
$_SERVER['REMOTE_PORT']
Returns the port being used on the user's machine to communicate with the web server
$_SERVER['SCRIPT_FILENAME']
Returns the absolute pathname of the currently executing script
$_SERVER['SERVER_ADMIN']
Returns the value given to the SERVER_ADMIN directive in the web server configuration file (if your script runs on a virtual host, it will be the value defined for that virtual host) (such as someone@w3scholls.com)
$_SERVER['SERVER_PORT']
Returns the port on the server machine being used by the web server for communication (such as 80)
$_SERVER['SERVER_SIGNATURE']
Returns the server version and virtual host name which are added to server-generated pages
$_SERVER['PATH_TRANSLATED']
Returns the file system based path to the current script
$_SERVER['SCRIPT_NAME']
Returns the path of the current script
$_SERVER['SCRIPT_URI']
Returns the URI of the current page

4) PHP $_REQUEST

4.1) PHP $_REQUEST is used to collect data after submitting an HTML form.
4.2) The example below shows a form with an input field and a submit button.
When a user submits the data by clicking on "Submit", the form data is sent to the file specified in the action attribute of the <form> tag.
In this example, we point to this file itself for processing form data.
If you wish to use another PHP file to process form data, replace that with the filename of your choice.
Then, we can use the super global variable $_REQUEST to collect the value of the input field:
<html>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
Name: <input type="text" name="fname">
<input type="submit">
</form>
<?php
$name = $_REQUEST['fname'];
echo $name;
?>
</body>
</html>

5) PHP $_POST

5.1) PHP $_POST is widely used to collect form data after submitting an HTML form with method="post". $_POST is also widely used to pass variables.
5.2) The example below shows a form with an input field and a submit button.
When a user submits the data by clicking on "Submit", the form data is sent to the file specified in the action attribute of the <form> tag.
In this example, we point to this file itself for processing form data.
If you wish to use another PHP file to process form data, replace that with the filename of your choice.
Then, we can use the super global variable $_POST to collect the value of the input field:
<html>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
Name: <input type="text" name="fname">
<input type="submit">
</form>
<?php
$name = $_POST['fname'];
echo $name;
?>
</body>
</html>
6) PHP $_GET
6.1) PHP $_GET can also be used to collect form data after submitting an HTML form with method="get".
6.2) $_GET can also collect data sent in the URL.
6.3) Assume we have an HTML page that contains a hyperlink with parameters:
<html>
<body>
<a href="test_get.php?subject=PHP&web=W3schools.com">Test $GET</a>
</body>
</html>
6.4) When a user clicks on the link "Test $GET", the parameters "subject" and "web" is sent to "test_get.php", and you can then acces their values in "test_get.php" with $_GET.
<html>
<body>
<?php
echo "Study " . $_GET['subject'] . " at " . $_GET['web'];
?>
</body>
</html>


Labels