簡體   English   中英

PHP / MYSQL:消除用戶輸入 - 這是一個壞主意嗎?

[英]PHP / MYSQL: Sanitizing user input - is this a bad idea?

我有一個“go”腳本來獲取所請求的任何其他腳本,這是我寫的用於清理用戶輸入的內容:

foreach ($_REQUEST as $key => $value){
    if (get_magic_quotes_gpc()) 
    $_REQUEST[$key] = mysql_real_escape_string(stripslashes($value));  
    else
    $_REQUEST[$key] = mysql_real_escape_string($value); 
}

我還沒有看到其他人使用這種方法。 有什么理由不去嗎?

編輯 - 修改為適用於數組:

function mysql_escape($thing) {
  if (is_array($thing)) {
    $escaped = array();
    foreach ($thing as $key => $value) {
      $escaped[$key] = mysql_escape($value);
    }          
    return $escaped;
  }
  // else
  if (get_magic_quotes_gpc()) $thing = stripslashes($thing);
  return mysql_real_escape_string($thing);
}

foreach ($_REQUEST as $key => $value){
    $_REQUEST[$key] = mysql_escape($value); 
}

我發現在使用數據時逃避數據要好得多,而不是在進行中。您可能希望在JSON,XML,Shell,MySQL,Curl或HTML中使用這些數據,並且每個數據都有自己的方式。逃避數據。


讓我們快速回顧一下為什么在不同的環境中需要逃避:

如果您使用引號分隔的字符串,則需要能夠轉義引號。 如果您使用的是xml,則需要將“內容”與“標記”分開如果您使用的是SQL,則需要將“命令”與“數據”分開如果您在命令行中,則需要分離“命令”來自“數據”

這一般是計算的一個基本方面。 因為分隔數據的語法可以在數據中出現,所以需要有一種方法來區分DATA和SYNTAX,從而逃避。

在Web編程中,常見的轉義案例是:1。將文本輸出到HTML 2.將數據輸出到HTML屬性3.將HTML輸出到HTML 4.將數據插入到Javascript中5.將數據插入到SQL中6.將數據插入到shell命令中

如果處理不當,每個都有不同的安全隱患。 這真的很重要! 讓我們在PHP的上下文中回顧一下:

  1. 文本轉換為HTML:htmlspecialchars(...)

  2. 數據轉換為HTML屬性htmlspecialchars(...,ENT_QUOTES)

  3. HTML轉換為HTML使用HTMLPurifier等庫來確保只存在有效標記。

  4. 數據到Javascript我更喜歡json_encode 如果要將其放在屬性中,則仍需要使用#2,例如

  5. 將數據插入SQL每個驅動程序都有某種類型的escape()函數。 這是最好的。 如果您使用普通的latin1字符集運行,則addslashes(...)是合適的。 不要忘記引號AROUND addslashes()調用:

    “INSERT INTO table1 SET field1 ='”。 addslashes($ data)。 “'”

  6. 命令行中的數據escapeshellarg()和escapeshellcmd() - 閱讀手冊

- 牢記這些,您將消除95%*的常見網絡安全風險! (* 一個推測)

如果$_REQUEST有數組,則它們的值將不會被清理。

我已經制作並使用了這個:

<?php
function _clean($var){
    $pattern = array("/0x27/","/%0a/","/%0A/","/%0d/","/%0D/","/0x3a/",
                     "/union/i","/concat/i","/delete/i","/truncate/i","/alter/i","/information_schema/i",
                     "/unhex/i","/load_file/i","/outfile/i","/0xbf27/");
    $value = addslashes(preg_replace($pattern, "", $var));
    return $value;
}

if(isset($_GET)){
    foreach($_GET as $k => $v){
        $_GET[$k] = _clean($v);
    }
}

if(isset($_POST)){
    foreach($_POST as $k => $v){
        $_POST[$k] = _clean($v);
    }
}
?>

您的方法會嘗試清理所有請求數據以插入數據庫,但是如果您只想輸出它呢? 輸出中會有不必要的反斜杠。 此外,無論如何,轉義不是防止SQL異常的好策略。 通過使用參數化查詢(例如在PDO或MySQLi中),您將“轉義”問題“傳遞”到抽象層。

除了沒有遞歸到數組和不必要的轉換,例如整數之外,這種方法在清理之前編碼用於SQL語句的數據。 mysql_real_escape_string()轉義數據,它不會消毒它 - 轉義和消毒不是一回事。

清理是許多PHP腳本在使用之前仔細檢查輸入數據的可接受性的任務。 我認為對未轉義的數據做得更好。 在進入SQL之前,我通常不會轉義數據。 那些喜歡使用預備語句的人就是這樣做的。

還有一件事:如果輸入數據可以包含utf8字符串,那么它們似乎應該在轉義之前進行驗證。 我經常在清理之前在$ _POST上使用遞歸的utf8清理器。

暫無
暫無

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

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