Viewed   55 times

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

I sanitize only one variable in GET by strip_tags. I am not sure whether I should sanitize everything or not, because last time in putting data to Postgres, the problem was most easily solved by the use of pg_prepare.



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 ‘&amp;’ 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.)

Thursday, November 17, 2022

All GET parameters will be strings (or an array of strings) in PHP. Use filter_var (or filter_input) and FILTER_VALIDATE_BOOLEAN:

Returns TRUE for "1", "true", "on" and "yes". Returns FALSE otherwise.

If FILTER_NULL_ON_FAILURE is set, FALSE is returned only for "0", "false", "off", "no", and "", and NULL is returned for all non-boolean values.

$hopefullyBool = filter_var($_GET['myVar'], FILTER_VALIDATE_BOOLEAN);

For INPUT vars that can be arrays there is filter_var_array and filter_input_array.

Another way to get the type boolean, pass something that evaluates to true or false like 0 or 1:

Then cast to boolean:

$hopefullyBool = (bool)$_GET['myVar'];

If you want to pass string true or false then another way:

$hopefullyBool = $_GET['myVar'] == 'true' ? true : false;

But I would say that filter_var with FILTER_VALIDATE_BOOLEAN was meant for this.

Sunday, August 21, 2022

If all you need is a GET request with custom headers and no body, you can use the following method that doesn't even need Curl:

$token = "SOMETHING"
$kahootId = '0c17fb60-76c6-424c-9326-d1154cbc70d3';
$url = ''.$kahootId;

$options = array(
    'http' => array(
        'method'  => 'GET',
        'header'  => "Authorization: ".$token."rn"

$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
Saturday, October 22, 2022

Use the skill command instead:

skill -9 -u username
Tuesday, November 15, 2022

I need exact matching only but among a set of values (IN clause of query).

So you need something other than exact matching. You can't possibly store a set of IDs in the ID property of your Person. QBE is clearly not the right tool for the job.

You can use Specifications, the Criteria API directly, QueryDSL, a dynamically composed JPQL query, or whatever other solution, but not QBE.

Friday, December 16, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :