What Is a Good Method to Sanitize the Whole $_Post Array in PHP

Sanitize $_POST and $_GET array inputs OOP

You don't need sanitize data before saving it to the database. More info here
https://security.stackexchange.com/questions/95325/input-sanitization-vs-output-sanitization

Sanitize array before echo PHP

I feel that you could benefit from some general information on the subject of sanitization and escaping.

  • To understand how to write secure PHP code, you need to prevent
    against XSS.
  • To prevent against XSS, you need to
    implement proper output escaping and may need to implement data sanitization.
  • To implement data sanitization and output escaping you need to understand why it's a problem and how to do it properly.

Sanitization

Sanitization should be done before saving the data to the database. It makes sure that things which shouldn't be saved to the database are not. It is also good to do it again after you read data out of your database incase you miss something and your database now contains something harmful. Generally if you are just storing text, you might want to allow any text to be saved and in this scenario sanitization is not really necessary. But it sounds like you are storing html...

If you are storing html you probably plan to output it to browsers at some point and you don't want it to contain harmful scripts for your users to execute. Sanitizing html to remove harmful javascript is actually very very difficult due to the many ways you can insert javascript. Whole PHP libraries (e.g. wp_kses_*) have been written dedicated to this and it's not enough to just remove all < script> tags as some SO answers suggest. Plus you will need to keep your html sanitization code up to date to prevent against the newest attacks. All in all, it's a very high risk/maintenance solution. If you want to go this route, there are some solutions here.

Usually you will want to give your users the ability to format their text with a subset of what html offers (e.g. bold, italics, underline and maybe some colours) and a better approach is to use a more lightweight language such as Markdown or BBCode

Also you should consider saving your fields as text only and handle the styling completely in your application.

Output Escaping

This is the step right before outputting the data. When you are piecing together HTML for output in PHP, you need to convert anything which isn't html yet in to safe html. If you use a templating language this is handled for you automatically. In my opinion it is the most misunderstood concept of PHP developers today, and unfortunately it is one of the most important. I won't go in to it here but I highly recommend this further reading.

Important Update

This code is NOT data sanitization, it is output escaping.

filter_var_array($row, FILTER_SANITIZE_SPECIAL_CHARS);

I can see now that confusingly, the word "Filter" has such a generic meaning in this answer and can arguably refer to both sanitization and escaping. I have removed it from my answer to help clear up any confusion.

Your example - Sanitization

I wont go as far to say never store html in a database field, but it is a lot harder this way. You need to decide what is expected and valid. If you update your question with more details on the specific data, it will become clear what these restrictions should be.

Your example - Output escaping

If your variables already contain well formed HTML fragment strings then you can safely append your variables using the "." (string concatenation operator) inside an open and close tag. What you have put in your question code is correct. However, I prefer to use direct output with short tags as it makes the code more readable and there is no real need to put everything in to a PHP string anyway.

<td><?= $row['tokens'] ?></td>
<td><?= $row['direction'] ?></td>
<td><?= $row['graph'] ?></td>
<td><?= $row['module'] ?></td>

Note: As explained above, by outputting html you are asking clients to trust, parse and display it. If these variables do in fact contain invalid or bad HTML, then it is a problem with your sanitization.

  • Output escaping should/does NOT clean your data.
  • Sanitization should/does NOT escape your data.

They are simply two different concepts working together.

Since your id should be an integer from your database you can cast it like this to make sure that it is.

<a href='upong.php?soya=<?= (int)$row['id'] ?>Specific type</a>

If the value is not castable to an integer (because something unexpected happened which you didn't account for) you end up with a 0 in your url which normally isn't that harmful.

Sanitizing user's data in GET by PHP

How do you sanitize data in $_GET -variables by PHP?

You do not sanitize data in $_GET. This is a common approach in PHP scripts, but it's completely wrong*.

All your variables should stay in plain text form until the point when you embed them in another type of string. There is no one form of escaping or ‘sanitization’ that can cover all possible types of string you might be embedding your values into.

So if you're embedding a string into an SQL query, you need to escape it on the way out:

$sql= "SELECT * FROM accounts WHERE username='".pg_escape_string($_GET['username'])."'";

And if you're spitting the string out into HTML, you need to escape it then:

Cannot log in as <?php echo(htmlspecialchars($_GET['username'], ENT_QUOTES)) ?>.

If you did both of these escaping steps on the $_GET array at the start, as recommended by people who don't know what they're doing:

$_GET['username']= htmlspecialchars(pg_escape_string($_GET['username']));

Then when you had a ‘&’ in your username, it would mysteriously turn into ‘&’ in your database, and if you had an apostrophe in your username, it would turn into two apostrophes on the page. Then when you have a form with these characters in it is easy to end up double-escaping things when they're edited, which is why so many bad PHP CMSs end up with broken article titles like “New books from O\\\\\\\\\\\\\\\\\\\'Reilly”.

Naturally, remembering to pg_escape_string or mysql_real_escape_string, and htmlspecialchars every time you send a variable out is a bit tedious, which is why everyone wants to do it (incorrectly) in one place at the start of the script. For HTML output, you can at least save some typing by defining a function with a short name that does echo(htmlspecialchars(...)).

For SQL, you're better off using parameterised queries. For Postgres there's pg_query_params. Or indeed, prepared statements as you mentioned (though I personally find them less managable). Either way, you can then forget about ‘sanitizing’ or escaping for SQL, but you must still escape if you embed in other types of string including HTML.

strip_tags() is not a good way of treating input for HTML display. In the past it has had security problems, as browser parsers are actually much more complicated in their interpretation of what a tag can be than you might think. htmlspecialchars() is almost always the right thing to use instead, so that if someone types a less-than sign they'll actually get a literal less-than sign and not find half their text mysteriously vanishing.

(*: as a general approach to solving injection problems, anyway. Naturally there are domain-specific checks it is worth doing on particular fields, and there are useful cleanup tasks you can do like removing all control characters from submitted values. But this is not what most PHP coders mean by sanitization.)

cleaning $_POST variables

What you're doing isn't enough. See here.



Related Topics



Leave a reply



Submit