簡體   English   中英

清理 PHP 中的查詢字符串

[英]Sanitize query string in PHP

我有一個帶有查詢字符串的網頁。

在 PHP 我有:

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

我需要清理查詢字符串嗎?
如果是,我該如何消毒,如果不消毒,可能會受到哪些攻擊?

如果您運行的是 PHP >= 5.2.0,請使用filter_inputfilter_input_array

假設您的 URL 和查詢字符串類似於http://example.com/?liquor=gin&mixer=tonic&garnish=lime

要過濾,您可以執行以下操作。

/*
 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 );

您應該使用htmlspecialchars($query, ENT_QUOTES)來防止任何 XSS 攻擊。

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

但是,您仍然應該將任何參數列入白名單,因為聰明的攻擊者可以偽造查詢並嘗試CSRF攻擊。

假設您在 PHP 5.x 中將查詢參數作為變量訪問,如下所示,但容易出現 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());
}


?>

防止來自 $_SERVER['QUERY_STRING'] 的 XSS

為了防止來自$_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());
}

?>

在這種情況下,您應該使用 urlencode 函數。

例如,當您要在鏈接的標題處輸出查詢參數的值時,htmlspecialchars/htmlentities 更合適,但在 href/src 屬性處不輸出。

您可以使用多種方式清理查詢,但這不是這樣做的地方。 即使您通過 GET 發送安全查詢,有人也可以更改地址欄上的查詢或使用篡改數據。 您必須清理 index.php(或處理數據的任何地方)。 如果您使用的是 MySQL,則必須以這種方式進行清理:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM