關於轉義

開發過程當中須要對用戶的輸入進行轉義,不管是安全地顯示用戶在表單提交中輸入的數據,仍是在處理 sql 語句時,進行安全地轉義能夠有效避免跨站腳本攻擊(XSS)和 SQL 注入。php

 

1. 使用 htmlentities() 和 htmlspecialchars()html

在處理用戶提交的表單數據時,先將用戶的輸入進行轉義,再顯示在頁面上。mysql

能夠使用 htmlentities() 和 htmlspecialchars() 函數將特殊字符轉換成 HTML 實體(例如把 < 轉換成 &lt;)。最基本的是 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));

   

參考:PHP防SQL注入不要再用addslashes和mysql_real_escape_string了

相關文章
相關標籤/搜索