As we have seen the internet is made of cats.
Unfortunately, not all these cats are cute and cuddly. There are some seriously bad cats out there intent on spoiling all our fun. As such we’d better turn our attention to improving the security on our PHP application. The mantra for web security is “Filter Inputs – Escape outputs”.
Filter Inputs
When we receive data from $_GET
and $_POST
we can’t be sure the data is not malicious in some way. Client side validation, with Javascript or HTML5, is not a barrier to someone sending data through to your application.
With the filter_var
method we can filter a variable to ensure it matches a particular type of data. The method will return FALSE if the filter fails.
filter_var(VARIABLE-TO-FILTER, FILTER-TYPE)
For example the following will take variables from $_POST
and filter them to ensure they are data type the application expects.
$userID = filter_var($_POST['userID'], FILTER_VALIDATE_INT); $userName = filter_var($_POST['userName'], FILTER_SANITIZE_STRING); $userEmail = filter_var($_POST['userEmail'], FILTER_VALIDATE_EMAIL);
To tackle the whole $_GET
or $_POST
if, for example, you expect all strings try:
$_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING); $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
Escape outputs
A common trick attempted by hacker is where they try to run their Javascript on your domain. They can attempt to do this by trying to get Javascript code into your database. Ideally you should clean this on the way in – but you can also clean it on the way back out to the user. Again we could use filter_var()
. In the following example the FILTER_SANITIZE_STRING
option will strip HTML tags from the target string so any attempt to run Javascript is fooled.
$string = "<script>nasty bad javascript</script>"; echo filter_var($string, FILTER_SANITIZE_STRING); echo $string;
More Techniques
In the above examples I have used filter_var
exclusively. However, there are other techniques available. For example the filter_input()
method is specifically designed to cleanse input variables.
filter_input(INPUT-TYPE, VARIABLE-NAME, FILTER-TYPE)
The input types available are INPUT_GET
, INPUT_POST
, INPUT_COOKIE
, INPUT_SERVER
, or INPUT_ENV
. Again, the method will return FALSE if the filter fails.
The following example will check a ‘posted’ variable $_POST['email']
.
if (!filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL)){ echo "Email is not valid"; }else{ echo "Email is valid"; }
When sanitizing variables to prevent misuse of any HTML
or Javascript in the data we could alternatively use strip_tags()
.
strip_tags(STRING, ALLOWABLE-TAGS)
By using the optional allowable tags parameter you can allow ‘innocent’ tags like <p>
and <br>
ie:
$myString = "<p>This is a paragraph.<br><script>alert('yo')</script></p>"; $myCleanString = strip_tags($myString, '<br><p>'); echo $myCleanString;
Do we need to still filter the variables when using mysqli prepared statements please?
Thank you.