開發過程當中須要對用戶的輸入進行轉義,不管是安全地顯示用戶在表單提交中輸入的數據,仍是在處理 sql 語句時,進行安全地轉義能夠有效避免跨站腳本攻擊(XSS)和 SQL 注入。php
1. 使用 htmlentities() 和 htmlspecialchars()html
在處理用戶提交的表單數據時,先將用戶的輸入進行轉義,再顯示在頁面上。mysql
能夠使用 htmlentities() 和 htmlspecialchars() 函數將特殊字符轉換成 HTML 實體(例如把 < 轉換成 <)。最基本的是 htmlspecialchars(),能夠轉義 4 個字符: < > " 和 &(能夠根據可選的參數決定轉義的字符)。對於更復雜的編碼,須要使用 htmlentities(),能夠對任何 HTML 實體進行轉換。sql
例:chrome
<?php $html = "<script>alert('<a href=\"http://baidu.com?user=dee&browser=chrome\">baidu.com</a>');</script>"; echo $html,PHP_EOL; //會彈出alert提示框 //瀏覽器右鍵查看源代碼 //<script>alert('<a href="http://baidu.com?user=dee&browser=chrome">baidu.com</a>');</script> echo htmlentities($html),PHP_EOL; //瀏覽器右鍵查看源代碼 //<script>alert('<a href="http://baidu.com?user=dee&browser=chrome">baidu.com</a>');</script> echo htmlspecialchars($html),PHP_EOL; //轉義雙引號 < > & //瀏覽器右鍵查看源代碼 //<script>alert('<a href="http://baidu.com?user=dee&browser=chrome">baidu.com</a>');</script> echo htmlspecialchars($html, ENT_QUOTES),PHP_EOL; //轉義雙引號和單引號 < > & //瀏覽器右鍵查看源代碼 //<script>alert('<a href="http://baidu.com?user=dee&browser=chrome">baidu.com</a>');</script> echo htmlspecialchars($html, ENT_NOQUOTES),PHP_EOL; //非單引號和雙引號 //瀏覽器右鍵查看源代碼 //<script>alert('<a href="http://baidu.com?user=dee&browser=chrome">baidu.com</a>');</script>
2. 防止注入攻擊,建議使用 PDO 的參數綁定瀏覽器
使用參數綁定時,PDO 會對各個參數加引號和進行轉義安全
例:服務器
<?php $user = 'root'; $pwd = ''; try{ $mysql = new PDO('mysql:host=127.0.0.1;port=3306;dbname=test', $user, $pwd); } catch(Exception $e) { print 'Database problem:'.$e->getMessage(); die; } $st = $mysql->prepare('INSERT INTO family (id,name,is_naive) VALUES (?,?,?)'); $st->execute(array('','Lee',0));
若是不使用參數綁定,則須要自行轉義:手動加引號,而且將 SQL 的通配符 _ 和 % 也進行 \ 轉義函數
<?php $user = 'root'; $pwd = ''; try{ $mysql = new PDO('mysql:host=127.0.0.1;port=3306;dbname=test', $user, $pwd); } catch(Exception $e) { print 'Database problem:'.$e->getMessage(); die; } $str = "dee's_ books%"; /*使用PDO::quote()自行轉義*/ echo $str,"<br />"; // dee's_ books% echo $safe = $mysql->quote($str),"<br />"; // 'dee\'s_ books%' $safe = strtr($safe, array('_'=>'\_', '%'=>'\%')); echo $safe; // 'dee\'s\_ books\%' $st = $mysql->query("SELECT * FROM files WHERE contents LIKE $safe");
注意:不管是自定義轉義仍是使用 PDO::quote() 轉義以前,都要判斷服務器是否開啓了魔法引號(magic_quotes_gpc 在 PHP 5.4.0 中被移除),若是開啓了 magic_quotes_gpc,則關閉或者使用 addlashes() 處理傳入的參數(儘可能關閉魔法引號):編碼
/* magic_quotes_sybase 爲 0 時,addlashes() 對 ' " \ 進行 \ 轉義 */ /* magic_quotes_sybase 爲 1 時,addlashes() 對 ' 進行 " 轉義 */ if(get_magic_quotes_gpc() && ! ini_get('magic_quotes_sybase')) { $str = stripslashes($str); } $st = $mysql->prepare('UPDATE files SET contents = ? WHERE id = 1'); $st->execute(array($str));