5-3
過濾變數
零、體會一下被駭的感覺...
- 請在帳號輸入框分別輸入底下內容試試(XSS攻擊):
- <img src="http://cdn.pingwest.com/wp-content/uploads/2015/07/hacker-big.jpg">
- <script>alert('XSS')</script>
一、外來變數
- 用post方法傳過來的,我們用 $_POST['變數名稱'] 接收。
- 用get方法傳過來的,我們用 $_GET['變數名稱'] 接收。
- 用 $_REQUEST['變數名稱'] 同時可接收來自 post、get 和 cookie 的變數 。
二、過濾外來變數
- 外來變數通常來自使用者輸入或者比較容易竄改,所以,一定要進行過濾。
- 若用內建的 htmlspecialchars($string) 來過濾的話,預設只轉化雙引號,不對單引號做轉義,所以,這樣用
htmlspecialchars($string,ENT_QUOTES)
更好。
- 另一個和
htmlspecialchars
很像的 htmlentities 函數並不適用中文,因為會連同中文字一起轉義。
- 用
htmlentities
和 htmlspecialchars
只能防止XSS攻擊,不能防止SQL隱碼攻擊。
$title = htmlspecialchars($_POST['title'], ENT_QUOTES);
- 改用PHP的 filter_var 過濾器亦有同樣效果:
$title = filter_var($_POST['title'], FILTER_SANITIZE_SPECIAL_CHARS);
三、 PHP的 filter_var 過濾器
- 可利用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,例如<會轉成< |
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驗證 |
四、過濾數字
- 一般過濾數字用
(int) $xxx
或 intval($xxx)
即可,會強制把輸入的內容變成數字。
- 亦可用
filter_var($num, FILTER_SANITIZE_NUMBER_INT)
來過濾,但和 intval 不太一樣,例如:
$num = "123其他文字456";
echo filter_var($num, FILTER_SANITIZE_NUMBER_INT) . "<br>";
echo (int) $num . "<br>";
echo intval($num) . "<br>";
-
用用 (int) $xxx
或 intval($xxx)
會得到 123,但用filter_var()
會得到 123456