:::

7-2 PHP的變數過濾

零、體會一下被駭的感覺...

  1. 請在網址欄http://localhost/index.php?op=後輸入底下內容試試(XSS攻擊):
    • <img src="http://cdn.pingwest.com/wp-content/uploads/2015/07/hacker-big.jpg">
    • <script>alert('XSS')</script>

一、外來變數(7.超級全域變數)

  1. 用post方法傳過來的,我們用 $_POST['變數名稱'] 接收。
  2. 用get方法傳過來的,我們用 $_GET['變數名稱'] 接收。
  3. 用 $_REQUEST['變數名稱'] 同時可接收來自 post、get 和 cookie 的變數 。

二、過濾外來變數

  1. 外來變數通常來自使用者輸入或者比較容易竄改,所以,凡是外面傳來的變數,一律要進行變數過濾。
  2. 一般讀出文字可用內建的 htmlspecialchars() 函數來過濾。
    • 直接用 htmlspecialchars($string) 的話,預設只轉化雙引號,不對單引號做轉義,所以,這樣用htmlspecialchars($string,ENT_QUOTES) 更好。
  3. 亦可利用PHP內建的 filter_var() 函數來過濾變數。
    • 幾種常用過濾方法,完整過濾器可由此查看
      名稱 功用
      FILTER_CALLBACK option可以讓開發者用自訂的function處理
      FILTER_SANITIZE_STRING 去除標籤或特殊字元(html標籤會直接被消除)
      FILTER_SANITIZE_ENCODED 與urlencode()相同,過濾特殊字串
      FILTER_SANITIZE_MAGIC_QUOTES 過濾針對SQL injection做過濾(例如單、雙引號)
      FILTER_SANITIZE_SPECIAL_CHARS 針對HTML做encoding,例如<會轉成&lt;
      FILTER_SANITIZE_EMAIL 過濾e-mail,刪除e-mail格式不該出現的字元(除了$-_.+!*'{}|^~[]`#%/?@&=和數字),例如a(b)@gmail.com會被過濾成ab@gmail.com
      FILTER_SANITIZE_URL 過濾URL,刪除URL格式不該出現的字元
      FILTER_SANITIZE_NUMBER_INT 刪除所有字元,只留下數字與+-符號
      FILTER_SANITIZE_NUMBER_FLOAT 刪除所有字元,只留下數字和+-.,eE
      FILTER_VALIDATE_INT 判斷數字是否有在範圍內
      FILTER_VALIDATE_BOOLEAN 判斷布林值,1、true、on、yes都會判斷成true,反之為false,若是這些以外的值會回傳NULL
      FILTER_VALIDATE_FLOAT 判斷是否為浮點數
      FILTER_VALIDATE_REGEXP 利用regexp做驗證
      FILTER_VALIDATE_URL URL驗證
      FILTER_VALIDATE_EMAIL e-mail驗證
      FILTER_VALIDATE_IP IP驗證
    • $op= isset($_REQUEST['op']) ? filter_var($_REQUEST['op'], FILTER_SANITIZE_SPECIAL_CHARS) : "";
    • filter_var($string, FILTER_SANITIZE_SPECIAL_CHARS) 換行麻煩,因此若要輸出HTML的換行文字過濾仍建議採用 htmlspecialchars($string, ENT_QUOTES); 對$smarty樣板輸出有較好支援性 {$content.directions|nl2br}
  4. 過濾數字: 數字的過濾,只要加個(int)即可,如$sn=(int)$_GET['sn'];
  5. 不同過濾器的運用時機:要在php檔案中運算用的,請用PHP來過濾,要寫入資料庫的,用資料庫的real_escape_string()來過濾。