简体   繁体   English

清理 PHP 中的查询字符串

[英]Sanitize query string in PHP

I have a webpage with a query string.我有一个带有查询字符串的网页。

In PHP I have:在 PHP 我有:

$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?如果是,我该如何消毒,如果不消毒,可能会受到哪些攻击?

If you're running PHP >= 5.2.0, use filter_input or filter_input_array .如果您运行的是 PHP >= 5.2.0,请使用filter_inputfilter_input_array

Let's say your URL and query string is something like http://example.com/?liquor=gin&mixer=tonic&garnish=lime .假设您的 URL 和查询字符串类似于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 );

You should use htmlspecialchars($query, ENT_QUOTES) to prevent any XSS attacks.您应该使用htmlspecialchars($query, ENT_QUOTES)来防止任何 XSS 攻击。

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.但是,您仍然应该将任何参数列入白名单,因为聪明的攻击者可以伪造查询并尝试CSRF攻击。

Lets say you are accessing the query params as variables in the PHP 5.x as follows but is prone to XSS假设您在 PHP 5.x 中将查询参数作为变量访问,如下所示,但容易出现 XSS

Vulnerable to XSS易受 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']防止来自 $_SERVER['QUERY_STRING'] 的 XSS

To prevent XSS from $_SERVER['QUERY_STRING'] ,为了防止来自$_SERVER['QUERY_STRING'] XSS,

  • Use htmlentities to read the $_SERVER['QUERY_STRING'] and decode the query string using html_entity_decode .使用htmlentities读取$_SERVER['QUERY_STRING']并使用html_entity_decode解码查询字符串。
  • Use parse_str to extract array of key values of query parameters.使用parse_str提取查询参数的键值数组。
  • 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.使用filter_var_array过滤和清理数组,将数组作为第一个参数进行清理,将FILTER_SANITIZE_ENCODED作为第二个参数。
  • Use extract to make keys php variables with respective values.使用extract来制作具有各自值的键 php 变量。
<?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());
}

?>

In this case you should use urlencode function.在这种情况下,您应该使用 urlencode 函数。

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.例如,当您要在链接的标题处输出查询参数的值时,htmlspecialchars/htmlentities 更合适,但在 href/src 属性处不输出。

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.即使您通过 GET 发送安全查询,有人也可以更改地址栏上的查询或使用篡改数据。 You have to sanitize on index.php (or wherever you process the data).您必须清理 index.php(或处理数据的任何地方)。 If you are using MySQL, you have to sanitize this way:如果您使用的是 MySQL,则必须以这种方式进行清理:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM