[英]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_input
或filter_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
<?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());
}
?>
To prevent XSS from $_SERVER['QUERY_STRING']
,为了防止来自
$_SERVER['QUERY_STRING']
XSS,
htmlentities
to read the $_SERVER['QUERY_STRING']
and decode the query string using html_entity_decode
.htmlentities
读取$_SERVER['QUERY_STRING']
并使用html_entity_decode
解码查询字符串。parse_str
to extract array of key values of query parameters.parse_str
提取查询参数的键值数组。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
作为第二个参数。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.