用PHP函數(shù)解決SQL injection 反斜杠
什么是魔術(shù)引號(hào)
當(dāng)打開時(shí),所有的 '(單引號(hào)),"(雙引號(hào)),\(反斜線)和 NULL 字符都會(huì)被自動(dòng)加上一個(gè)反斜線進(jìn)行轉(zhuǎn)義。這和 addslashes() 作用完全相同。
一共有三個(gè)魔術(shù)引號(hào)指令:
magic_quotes_gpc 影響到 HTTP 請(qǐng)求數(shù)據(jù)(GET,POST 和 COOKIE)。不能在運(yùn)行時(shí)改變。在 PHP 中默認(rèn)值為 on。 參見 get_magic_quotes_gpc()。
magic_quotes_runtime 如果打開的話,大部份從外部來源取得數(shù)據(jù)并返回的函數(shù),包括從數(shù)據(jù)庫和文本文件,所返回的數(shù)據(jù)都會(huì)被反斜線轉(zhuǎn)義。該選項(xiàng)可在運(yùn)行的時(shí)改變,在 PHP 中的默認(rèn)值為 off。 參見 set_magic_quotes_runtime() 和 get_magic_quotes_runtime()。
magic_quotes_sybase 如果打開的話,將會(huì)使用單引號(hào)對(duì)單引號(hào)進(jìn)行轉(zhuǎn)義而非反斜線。此選項(xiàng)會(huì)完全覆蓋 magic_quotes_gpc。如果同時(shí)打開兩個(gè)選項(xiàng)的話,單引號(hào)將會(huì)被轉(zhuǎn)義成 ''。而雙引號(hào)、反斜線 和 NULL 字符將不會(huì)進(jìn)行轉(zhuǎn)義。 如何取得其值參見 ini_get()。
addslashes — 使用反斜線引用字符串
說明
string addslashes ( string $str )
返回字符串,該字符串為了數(shù)據(jù)庫查詢語句等的需要在某些字符前加上了反斜線。這些字符是單引號(hào)(')、雙引號(hào)(")、反斜線(\)與 NUL(NULL 字符)。
一個(gè)使用 addslashes() 的例子是當(dāng)你要往數(shù)據(jù)庫中輸入數(shù)據(jù)時(shí)。例如,將名字 O'reilly 插入到數(shù)據(jù)庫中,這就需要對(duì)其進(jìn)行轉(zhuǎn)義。大多數(shù)據(jù)庫使用 \ 作為轉(zhuǎn)義符:O\'reilly。這樣可以將數(shù)據(jù)放入數(shù)據(jù)庫中,而不會(huì)插入額外的 \。當(dāng) PHP 指令 magic_quotes_sybase 被設(shè)置成 on 時(shí),意味著插入 ' 時(shí)將使用 ' 進(jìn)行轉(zhuǎn)義。
默認(rèn)情況下,PHP 指令 magic_quotes_gpc 為 on,它主要是對(duì)所有的 GET、POST 和 COOKIE 數(shù)據(jù)自動(dòng)運(yùn)行 addslashes()。不要對(duì)已經(jīng)被 magic_quotes_gpc 轉(zhuǎn)義過的字符串使用 addslashes(),因?yàn)檫@樣會(huì)導(dǎo)致雙層轉(zhuǎn)義。遇到這種情況時(shí)可以使用函數(shù) get_magic_quotes_gpc() 進(jìn)行檢測。
stripslashes
(PHP 4, PHP 5)
stripslashes — Un-quote string quoted with addslashes()
說明
string stripslashes ( string $str )
Un-quotes a quoted string.
Note: If magic_quotes_sybase is on, no backslashes are stripped off but two apostrophes are replaced by one instead.
SQL injection問題在ASP上可是鬧得沸沸揚(yáng)揚(yáng)?5比換褂脅簧俟?內(nèi)外著名的PHP程序“遇難”。至于SQL injection的詳情,網(wǎng)上的文章太多了,在此就不作介紹。
如 果你網(wǎng)站空間的php.ini文件里的magic_quotes_gpc設(shè)成了off,那么PHP就不會(huì)在敏感字符前加上反斜杠(\),由于表單提交的內(nèi) 容可能含有敏感字符,如單引號(hào)('),就導(dǎo)致了SQL injection的漏洞。在這種情況下,我們可以用addslashes()來解決問題,它會(huì)自動(dòng)在敏感字符前添加反斜杠。
但是,上面的方法只 適用于magic_quotes_gpc=Off的情況。作為一個(gè)開發(fā)者,你不知道每個(gè)用戶的magic_quotes_gpc是On還是Off,如果把 全部的數(shù)據(jù)都用上addslashes(),那不是“濫殺無辜”了?假如magic_quotes_gpc=On,并且又用了addslashes()函 數(shù),那讓我們來看看:- <?php
- //如果從表單提交一個(gè)變量$_POST['message'],內(nèi)容為 Tom's book
- //這此加入連接MySQL數(shù)據(jù)庫的代碼,自己寫吧
- //在$_POST['message']的敏感字符前加上反斜杠
- $_POST['message'] = addslashes($_POST['message']);
- //由于magic_quotes_gpc=On,所以又一次在敏感字符前加反斜杠
- $sql = "INSERT INTO msg_table VALUE('$_POST[message]');";
- //發(fā)送請(qǐng)求,把內(nèi)容保存到數(shù)據(jù)庫內(nèi)
- $query = mysql_query($sql);
- //如果你再從數(shù)據(jù)庫內(nèi)提取這個(gè)記錄并輸出,就會(huì)看到 Tom\'s book
- ?>
復(fù)制代碼 這樣的話,在magic_quotes_gpc=On的環(huán)境里,所有輸入的單引號(hào)(')都會(huì)變成(\')……
其 實(shí)我們可以用get_magic_quotes_gpc()函數(shù)輕易地解決這個(gè)問題。當(dāng)magic_quotes_gpc=On時(shí),該函數(shù)返回TRUE; 當(dāng)magic_quotes_gpc=Off時(shí),返回FALSE。至此,肯定已經(jīng)有不少人意識(shí)到:問題已經(jīng)解決。請(qǐng)看代碼:- <?php
- //如果magic_quotes_gpc=Off,那就為提單提交的$_POST['message']里的敏感字符加反斜杠
- //magic_quotes_gpc=On的情況下,則不加
- if (!get_magic_quotes_gpc()) {
- $_POST['message'] = addslashes($_POST['message']);
- } else {}
- ?>
復(fù)制代碼 其實(shí)說到這里,問題已經(jīng)解決。下面再說一個(gè)小技巧。
有時(shí)表單提交的變量不止一個(gè),可能有十幾個(gè),幾十個(gè)。那么一次一次地復(fù)制/粘帖addslashes(),是否麻煩了一點(diǎn)?由于從表單或URL獲取的數(shù)據(jù)都是以數(shù)組形式出現(xiàn)的,如$_POST、$_GET)?D薔妥遠(yuǎn)ㄒ逡桓隹梢浴昂嶸ㄇЬ?”的函數(shù):- <?php
- function quotes($content)
- {
- //如果magic_quotes_gpc=Off,那么就開始處理
- if (!get_magic_quotes_gpc()) {
- //判斷$content是否為數(shù)組
- if (is_array($content)) {
- //如果$content是數(shù)組,那么就處理它的每一個(gè)單無
- foreach ($content as $key=>$value) {
- $content[$key] = addslashes($value);
- }
- } else {
- //如果$content不是數(shù)組,那么就僅處理一次
- addslashes($content);
- }
- } else {
- //如果magic_quotes_gpc=On,那么就不處理
- }
- //返回$content
- return $content;
- }
- ?>
復(fù)制代碼 |