我有一个带查询字符串的网页。
在PHP中,我有以下代码:
$querystring=$_SERVER["QUERY_STRING"];
echo "<html><head></head><body>
<a href='index.php?$querystring'>test</a>
</body></html>";
我需要对查询字符串进行清理吗?
如果需要,如何进行清理?如果不进行清理可能会有哪些攻击方式?
我有一个带查询字符串的网页。
在PHP中,我有以下代码:
$querystring=$_SERVER["QUERY_STRING"];
echo "<html><head></head><body>
<a href='index.php?$querystring'>test</a>
</body></html>";
我需要对查询字符串进行清理吗?
如果需要,如何进行清理?如果不进行清理可能会有哪些攻击方式?
/*
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 );
为了防止任何 XSS 攻击,您应该使用 htmlspecialchars($query, ENT_QUOTES)
。
echo "<html><head></head><body>
<a href='index.php?".htmlspecialchars($querystring, ENT_QUOTES)."'>test</a>
</body></html>"
但是,你仍然应该白名单任何参数,因为聪明的攻击者可能会伪造查询并尝试跨站请求伪造攻击。
<?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());
}
?>
为了预防来自$_SERVER['QUERY_STRING']
的XSS攻击,
htmlentities
读取$_SERVER['QUERY_STRING']
并解码查询字符串使用html_entity_decode
。parse_str
提取查询参数的键值数组。filter_var_array
过滤和清理数组,将要清理的数组作为第一个参数,并使用FILTER_SANITIZE_ENCODED
作为第二个参数。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());
}
?>
您可以使用多种方式对查询进行清理,但那不是做这件事的地方。即使您通过GET发送了一个安全的查询,某人仍然可以在地址栏上或使用篡改数据更改查询。您必须在index.php(或任何其他处理数据的地方)上进行清理。如果您正在使用MySQL,则必须以以下方式进行清理:
$field = mysql_real_scape($_GET['field']);