Query re "Don’t waste time attempting to ‘sanitize’ data to try to make it safe"

Hi, I am starting a new thread rather hijacking someone else’s - I hope that is appropriate?

In the thread “Problem with syntax in PHP str_replace” @mabismad gave a great list of points of good practice in PHP which was very interesting and great to see and I have bookmarked it for reference.

I wanted to ask about item no.8

I wonder if might ask for more detailed advice about this. I have no formal training in IT/computers/coding and am just an interested amateur. If, for instance, you have some user input as a number from a form and you wish to echo the result of a calculation based on this number - would you need to do anything more than simply

$metres = $_POST['metres'];
echo $metres * 2.54;

?
As I type this, I realise that perhaps you don’t need to “sanitise” this input and that is the point that you are making?

Whereas if you were going to use the input to create a SQL query, as well as using prepared statements you would need to do some “sanitising” of the data? If so, what is your preferred means of sanitisation in this senario? And how about for use with mail()?

I hope you don’t mind me asking and I hope you aren’t sick of people asking you about it?

1 Like

In an HTML output context you need to run user supplied data through htmlspecialchars. There is no need to create a variable for nothing. Of course you may want to VALIDATE the data, but not change it (Sanitize).

If you do not do this you will create an XSS Attack vulnerability.

echo htmlspecialchars($_POST[‘metres’]) * 2.54;

In an SQL context you leave it alone (still validate) and use Prepared Statements to insert the data. And again , outputting to HTML from the DB you would use htmlspecialchars.That’s it.

3 Likes

Thank you.

By validate do mean eg make sure it is a valid email address, make sure a number is a number etc?

Yes.

1 Like

Please supply a typical example of $_POST[‘metres’]) that would cause problems.

Also would it be adequate to cast the $_POST variable? Please supply reasons and explain why it could be vunerable.

$metres = (float) $_POST['metres'] * 2.54;

1 Like

Hi John,

Please supply a typical example of $_POST[‘metres’]) that would cause problems.

As far as just the POST request itself, this would be a typical example to demonstrate an XSS vulnerability. (There are many exploits that could be done with this.)

if($_SERVER['REQUEST_METHOD'] == 'POST'){
echo $_POST['metres'];
}
?>
<form method="post">
 <input name="metres" value = '<script>alert("Hacked");</script>'>
 <input type="submit" value="Submit">
</form>

Also would it be adequate to cast the $_POST variable?

Casting is to convert one type to another. It is not intended for XSS mitigation. What you should do is validate the user supplied data before you use it.

And for anyone that doesn’t know the Golden Rule,
"Never Ever Trust User Supplied Data"

4 Likes

Simply casting can produce unwanted errors. A text string may be cast to 0 when it maybe should be rejected as invalid data.
Validate client side, Eg:-

<input type="number" name="metres" step="0.01">

Then server side, Eg:-

if(!is_numeric($_POST['metres'])){
	$valErrors[] = 'Metres value should be a number!';
}

Then you may cast the certified numeric string to a float and do as you will with it.

2 Likes

The general principle at play here is FIEO: Filter Input, Escape Output.

Filter input: make sure that any data you receive from “the outside world” (through a form, email, message, etc) adheres to what you’d expect. If not, refuse the data. In some cases there might be an easy way to transform data that doesn’t adhere to the specification such that it does, but that is only interesting from a UX point of view, not from a security point of view.

Escape output: once you’ve filtered the input, assume you made a mistake and it didn’t fully work, so just to be the safe side escape the data when it’s sent back to “the outside world” (i.e. a browser) again.

3 Likes

I am starting to use FILTER_SANITIZE_STRING insted of htmlspecialchars, at least for forwarding by email.

I am also aware of the option to use filter_input with the INPUT_POST parameter.

I think insignificant time is wasted by sanitizing data.