David19801
David19801

Reputation: 11448

Sanitize query string in PHP

I have a webpage with a query string.

In PHP I have:

$querystring=$_SERVER["QUERY_STRING"];
echo "<html><head></head><body>
<a href='index.php?$querystring'>test</a>
</body></html>";

Do I need to sanitize the querystring?
If yes, how do I sanitize and what are some possible attacks if I don't?

Upvotes: 12

Views: 25347

Answers (5)

webinista
webinista

Reputation: 3764

Update: FILTER_SANITIZE_STRING is deprecated since PHP 8.1, see official PHP documentation: https://www.php.net/manual/en/filter.filters.sanitize.php


If you're running PHP >= 5.2.0, use filter_input or filter_input_array.

Let's say your URL and query string is something like http://example.com/?liquor=gin&mixer=tonic&garnish=lime.

To filter, you would do something like the following.

/*
 FILTER_SANITIZE_STRING removes most dangerous characters. That may 
 not always be what you want. Read the PHP filters docs. 
 
 We are also overwriting the $_GET array (the query string) with the sanitized
 versions of these variables.
*/

$_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);

/* 
rebuild query string using white listed variables, 
not $_GET to prevent variable injection as Mārtiņš Briedis 
suggests above.
*/

$qv['liquor']  = $_GET['liquor'];
$qv['mixer']   = $_GET['mixer'];
$qv['garnish'] = $_GET['garnish'];

# build and URL encode the query string using the above array.
$querystring = http_build_query( $qv );

Upvotes: 21

navule
navule

Reputation: 3654

Lets say you are accessing the query params as variables in the PHP 5.x as follows but is prone to XSS

Vulnerable to XSS

<?php
// http://example.com/mypage.php?a=hi&b=wow&c=<script type='text/javascript'>alert('XSS Attacked!');</script>

try{
    $q = $_SERVER['QUERY_STRING'];
    parse_str( $q, $arr );
    extract($arr);
    echo '<pre>';
    echo 'a is = ' . $a;
    echo PHP_EOL;
    echo 'b is = ' . $b;
    echo PHP_EOL;
    echo 'c is = ' . $c;
    echo '</pre>';

}
catch(Exception $e){
    error_log($e->getMessage());
}


?>

Prevent XSS from $_SERVER['QUERY_STRING']

To prevent XSS from $_SERVER['QUERY_STRING'],

  • Use htmlentities to read the $_SERVER['QUERY_STRING'] and decode the query string using html_entity_decode.
  • Use parse_str to extract array of key values of query parameters.
  • Filter and Sanitize the array using filter_var_array with array to sanitize as the first arg and FILTER_SANITIZE_ENCODED as the second argument.
  • Use extract to make keys php variables with respective values.
<?php
// http://example.com/mypage.php?a=hi&b=wow&c=<script type='text/javascript'>alert('XSS Attacked!');</script>
try{
    $q = htmlentities($_SERVER['QUERY_STRING']);
    parse_str( html_entity_decode($q), $arr );
    $arr=filter_var_array($arr, FILTER_SANITIZE_ENCODED);
    extract($arr);
    echo '<pre>';
    echo 'a is = ' . $a;
    echo PHP_EOL;
    echo 'b is = ' .  $b;
    echo PHP_EOL;
    echo 'c is = ' .  $c;
    echo '</pre>';

}
catch(Exception $e){
    error_log($e->getMessage());
}

?>

Upvotes: 1

phobia82
phobia82

Reputation: 1257

You can sanitize the query using several ways, but that is not the place to do that. Even if you send a safe query by GET, someone can change the query on the address bar or using tamper data. You have to sanitize on index.php (or wherever you process the data). If you are using MySQL, you have to sanitize this way:

$field = mysql_real_scape($_GET['field']);

Upvotes: -3

Boris Belenski
Boris Belenski

Reputation: 1412

In this case you should use urlencode function.

htmlspecialchars/htmlentities are more appropriate when you are going to output value of the query param at the link's title for example, but no at the href/src attributes.

Upvotes: 0

Mārtiņš Briedis
Mārtiņš Briedis

Reputation: 17772

You should use htmlspecialchars($query, ENT_QUOTES) to prevent any XSS attacks.

echo "<html><head></head><body>
<a href='index.php?".htmlspecialchars($querystring, ENT_QUOTES)."'>test</a>
</body></html>"

But still, you should white list any parameters, because a smart attacker could forge a query and attempt a CSRF attack.

Upvotes: 10

Related Questions