2011-02-16 39 views
1

我把一個網站放在一起,(我們已經使用javascript在客戶端進行預驗證)。但是在厭倦了每隔一行編寫mysql_real_escape_string之後。我寫了這個類,它只有兩個函數,主要集中在用戶輸入/ sql中清理數據。我的問題是,有哪些方法可以實現更簡單的輸入消毒,同時提高代碼可讀性?什麼是改善我的PHP數據衛生課程的方法?

<?php 
class Safe { 
    function userinput($string){ 
     $string = strip_tags($string); 
     $string = htmlspecialchars($string); 
     return $string; 
    } 
    function sql ($string){ 
     $sqlstuff = Array("union", "select", "update", "delete", "outfile", "create"); 
     $string = Safe::str($string); 
     $string = mysql_escape_string($string); 
     $string = str_ireplace($sqlstuff, "", $string); 
     return $string; 

    } 
} 
?> 
+0

看起來像從sql替換那些常見的單詞將導致您的問題取決於客戶端發送什麼。不過,我會建議使用SQL抽象層(如PDO),並使用它的佔位符能力來執行SQL衛生。 (strip_tags仍然是一個好主意) – Cfreak 2011-02-16 22:01:33

回答

2

使用這樣的類是一個好主意,特別是如果它簡化了輸入處理。不過有我要評論談幾點:

  • 您應該使用mysql_ real_ escape_string代替PHP3函數mysql_escape_string。
  • 第一個函數應該叫html什麼的。 userinput聽起來模糊和歪曲。
  • HTML轉義需要更多參數htmlspecialchars($str, ENT_QUOTES, "UTF-8")非常安全
  • 危險SQL關鍵字的黑名單並不是一個好主意。它暗示了使用SQL查詢的錯誤方法(如果您通過HTTP請求接收查詢,那就是您的問題)。
    • 此外,你不應該嘗試過濾它們。而是檢測到它們,寫入錯誤/安全日誌,並立即死亡()。如果試圖規避安全性,那麼嘗試對請求進行「清理」就毫無意義。
5

對不起,這聽起來很刺耳,但是你的班完全壞了。

  • 您不應該使用htmlspecialchars進行消毒輸入,它僅用於轉義輸出。您不需要將HTML編碼插入數據庫,也不需要。在向瀏覽器發送輸出時只使用htmlspecialchars
  • 您不應該從輸入中剝離標籤,而應在使用htmlspecialchars時稍後輸出該數據,以確保HTML標籤被轉義且不被瀏覽器解釋您應該使用PDO。如果您正在編寫一個新網站,那麼絕對沒有理由不能正確開始並使用PDO。 做到這一點
  • 你不應該過濾出「聯合」,「選擇」等,這是愚蠢的。這些詞可以用普通的英語表達,如果你正確地轉義了PDO爲你處理的引語,它們是無害的。

再次,對於這個答案的苛刻語氣感到遺憾,但是廢棄整個事情並使用PDO。這裏幾乎沒有可挽救的東西。

+0

沒關係,這是我的第一次嘗試。我會考慮這些觀點。過濾這個詞似乎是個好主意,但我會檢查PDO。 – stokkseyri 2011-02-16 22:12:44

2

您也可以使用捆綁於PHP filter_*功能,併爲您提供的機制,根據特定的過濾規則來過濾請求參數。

隨着few extra tricks,你甚至可以過濾不同類型的數據(感謝erisco!)。

class sanitizer { 

    public function sanitizeValues($values, $filters) { 

    $defaultOptions=FILTER_FLAG_NO_ENCODE_QUOTES | FILTER_FLAG_STRIP_LOW | FILTER_NULL_ON_FAILURE; 

    $filters=(array)$filters; 
    $values=(array)$values; 
    foreach ($filters as $key => $filter) { 
     if($parts=explode('/', $key)){ 
      $v=&$values; 
      foreach ($parts as $part){ 
       $v=&$v[$part]; 
      } 
      $filter=(array)$filter; 
      $filter[1]=isset($filter[1])?$filter[1]:$defaultOptions; 
      $v=filter_var($v, $filter[0], $filter[1]); 
      // consider if you really need this here instead of PDO 
      // $v=mysql_real_escape_string($v); 
     } 
     else{ 
      $values[$key]=isset($values[$key]) ? filter_var($values[$key], $filter[0], $filter[1]) : null; 
     } 

    } 
    return $values; 
    } 
} 

$manager=sanitizer::sanitizeValues($_GET['manager'], array(
       'manager/managerID'=>FILTER_VALIDATE_INT,   
       'manager/username'=>FILTER_SANITIZE_STRING, 
       'manager/name'=>FILTER_SANITIZE_STRING, 
       'manager/email'=>FILTER_SANITIZE_STRING, 
       'manager/phone'=>FILTER_SANITIZE_STRING, 
       'manager/bio'=>FILTER_SANITIZE_STRING, 
       'manager/enabled'=>FILTER_VALIDATE_BOOLEAN, 
       'manager/password'=>FILTER_SANITIZE_STRING)); 

這將產生一個完整的陣列與基於在所述_GET「管理器」參數所需的所有領域,具有所有值過濾和任選的逃脫。