說說PHP中的SQL注入

最近在工作中遇到一個 SQL 注入,雖然影響不是很大,但也足夠讓我靜下來思考掖桦,SQL 注入問題好像很簡單、好像每個人都明白供汛,但在實際的開發(fā)中還是會出現(xiàn)這樣低級的錯誤枪汪,出現(xiàn)這樣的問題個人覺得和 PHP 開發(fā)隨意化有關(guān)涌穆,第二個原因可能是沒有明白 SQL 注入的原理。

什么是 SQL 注入

在應用程序中料饥,為了和用戶交互蒲犬,允許用戶輸入數(shù)據(jù),假如開發(fā)者不慎重出現(xiàn)漏洞岸啡,攻擊者輸入一些特殊的字符從而讓應用程序執(zhí)行了危險的 SQL 操作原叮。危險可大可小,小的泄漏了機密數(shù)據(jù)(比如用戶信息)巡蘸,大的危害可能會刪除整個數(shù)據(jù)庫奋隶。

SQL 注入根本的原因就在于被攻擊者構(gòu)建了危險的 SQL,看 PHP 中的一個例子:

$sql = "select * from tb where name='" . $name . "'";
mysql_query($sql);

這時候假如 $name 的值被惡意輸入 1' OR '1'='1悦荒,則最后的 SQL 就是select * from tb where name='1' OR '1'='1'唯欣,從而查詢出了所有的表數(shù)據(jù),這就是比較簡單的 SQL 注入搬味。

構(gòu)建危險 SQL 的主要原因在于 SQL 語句中的“雙引號”境氢、“單引號”、“關(guān)鍵字”碰纬。利用這些字符攻擊者可以構(gòu)建出很多其他語義的 SQL萍聊。

如何避免 SQL 注入

上面說到 SQL 注入的原因在于“雙引號”、“單引號”悦析、“關(guān)鍵字”寿桨,所以預防的方法就在于“破壞”這些特殊字符。主要有兩種方法:

(1)過濾數(shù)據(jù)

在開發(fā)程序的時候强戴,根據(jù)應用的限制亭螟,應該明確規(guī)定用戶輸入的數(shù)據(jù)是什么類型的,比如是字符串骑歹,還是整型预烙,或者是富文本數(shù)據(jù),應用程序就必須嚴格的限制陵刹,比如某些輸入假如過濾了“單引號”等特殊符號默伍,自然就構(gòu)建不起危險的 SQL 了。

為什么在 PHP 語言中會出現(xiàn)很多的低級操作呢衰琐?有部分原因就在于 PHP 太靈活了,比如在數(shù)據(jù)層直接使用$_GET變量的值構(gòu)建 SQL炼蹦,從而導致問題羡宙。當然這不完全是語言的問題,主要在于語言結(jié)構(gòu)太靈活掐隐,開發(fā)者肆無忌憚導致的狗热。

(2)轉(zhuǎn)義數(shù)據(jù)

由于“雙引號”钞馁、“單引號”等特殊字符在 SQL 語句中有特殊的能力(指令),所以用戶輸入的這些特殊符號在構(gòu)建 SQL 的時候就也有了特殊的含義匿刮,假如我們通過一種方式讓用戶輸入的特殊符號沒有其特殊能力(只有字符本身的含義)僧凰,那么就不會出現(xiàn) SQL 注入了,這種方式就是轉(zhuǎn)義熟丸,在 MySql 中內(nèi)置了這樣的函數(shù) mysql_real_escape_string()训措。

SQL 中 select/update/delete/insert 語句都需要轉(zhuǎn)義,對于 insert 語句來說光羞,轉(zhuǎn)義不代表插入的數(shù)據(jù)在表中多了個反斜杠字符绩鸣,這個概念一定要清楚,在數(shù)據(jù)庫存儲里面是不會放入反斜杠轉(zhuǎn)義符號的纱兑。

接下來重點看看如何在 PHP 中進行轉(zhuǎn)義數(shù)據(jù)呀闻。

mysql(mysqli) 擴展庫

PHP 語言是從 C 語言發(fā)展而來的,所以早期其實很多函數(shù)和 C 語言函數(shù)同名潜慎,這也說明大部分 PHP 函數(shù)的實現(xiàn)就是調(diào)用 C 語言函數(shù)庫捡多。MySql 擴展就是典型的一個函數(shù)庫(調(diào)用本地的 C 命令函數(shù)庫)。

PHP 中的 mysql_real_escape_string() 函數(shù)就是執(zhí)行轉(zhuǎn)義的铐炫,只要在輸入的數(shù)據(jù)變量上調(diào)用這個函數(shù)垒手,就能解決大部分注入問題。

這個函數(shù)很簡單驳遵,這里說說一個很古老的函數(shù) addslashes()淫奔,在我早期使用 PHP 過程中,經(jīng)常遇到這個函數(shù)堤结,它也能對字符串進行轉(zhuǎn)義唆迁,所以很多人用它代替 mysql_real_escape_string() 函數(shù),其實這是不對的一種方法竞穷,因為兩者轉(zhuǎn)義的具體字符是不一樣的唐责,同時 addslashes() 不并是專門用戶轉(zhuǎn)義數(shù)據(jù)庫中的字符。

拋開數(shù)據(jù)庫操作來說瘾带,在如今的 PHP 中也不建議使用 addslashes() 函數(shù)鼠哥,在 PHP 早期版本中,$_GET$_POST 數(shù)據(jù)會自動進行 addslashes() 調(diào)用(猜測是為了保證數(shù)據(jù)的安全)看政,可也破壞了一個規(guī)則——不應該修改用戶的原始數(shù)據(jù)朴恳,所以在新版本 PHP 中,這個函數(shù)對應的 magic_quotes_gpc 指令是關(guān)閉的允蚣,但是從我的角度來看于颖,PHP 開發(fā)者應該盡量去忘記這個函數(shù)的存在。

PDO

如何理解 PDO 呢嚷兔?可以看看 mysqli 包的一些弱點:

  • PHP 開發(fā)者可能會操作 MySql 或者其他類型的數(shù)據(jù)庫森渐,但是 mysqli 庫只能操作 MySql,對于 PHP 開發(fā)者來說沒有統(tǒng)一的接口去操作 SQL 語言(注意不是操作數(shù)據(jù)庫)做入。
  • mysqli 上的一些 SQL 操作功能缺乏,比如沒有事務處理等等同衣。

而 PDO 就能解決上述兩個問題竟块,而具體到轉(zhuǎn)義操作上,PDO 通過Prepared Queries讓你來構(gòu)建更安全的 SQL 語句耐齐,對于 mysql_real_escape_string() 來說開發(fā)者還是需要自己構(gòu)建 SQL 語句浪秘,而 PDO 可以提供更優(yōu)雅的方式操作 SQL。

$stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name");
$stmt->execute(array(':name' => $name, ':id' => $id));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

$stmt = $db->prepare("UPDATE table SET name=? WHERE id=?");
$stmt->execute(array($name, $id));
$affected_rows = $stmt->rowCount();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蚪缀,一起剝皮案震驚了整個濱河市秫逝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌询枚,老刑警劉巖违帆,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異金蜀,居然都是意外死亡刷后,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門渊抄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尝胆,“玉大人,你說我怎么就攤上這事护桦『危” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵二庵,是天一觀的道長贪染。 經(jīng)常有香客問我,道長催享,這世上最難降的妖魔是什么杭隙? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮因妙,結(jié)果婚禮上痰憎,老公的妹妹穿的比我還像新娘。我一直安慰自己攀涵,他們只是感情好铣耘,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著以故,像睡著了一般涡拘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上据德,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天鳄乏,我揣著相機與錄音,去河邊找鬼棘利。 笑死橱野,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的善玫。 我是一名探鬼主播水援,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼茅郎!你這毒婦竟也來了蜗元?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤系冗,失蹤者是張志新(化名)和其女友劉穎奕扣,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掌敬,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡惯豆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了奔害。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片楷兽。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖华临,靈堂內(nèi)的尸體忽然破棺而出芯杀,到底是詐尸還是另有隱情,我是刑警寧澤雅潭,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布揭厚,位于F島的核電站,受9級特大地震影響寻馏,放射性物質(zhì)發(fā)生泄漏棋弥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一诚欠、第九天 我趴在偏房一處隱蔽的房頂上張望顽染。 院中可真熱鬧,春花似錦轰绵、人聲如沸粉寞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唧垦。三九已至,卻和暖如春液样,著一層夾襖步出監(jiān)牢的瞬間振亮,已是汗流浹背巧还。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留坊秸,地道東北人麸祷。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像褒搔,于是被迫代替她去往敵國和親阶牍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Php:腳本語言星瘾,網(wǎng)站建設走孽,服務器端運行 PHP定義:一種服務器端的HTML腳本/編程語言,是一種簡單的、面向?qū)ο?..
    廖馬兒閱讀 2,137評論 2 38
  • Welcome 目前網(wǎng)絡上充斥著大量的陳舊信息琳状,讓PHP新手誤入歧途磕瓷,傳播著錯誤的實踐和糟糕的代碼,這必須得到糾正...
    layjoy閱讀 21,672評論 7 118
  • Composer Repositories Composer源 Firegento - Magento模塊Comp...
    零一間閱讀 3,958評論 1 66
  • Web安全簡史 在Web1.0時代算撮,人們更多是關(guān)注服務器端動態(tài)腳本語言的安全問題生宛,比如將一個可執(zhí)行腳本(俗稱Web...
    潘良虎閱讀 3,929評論 3 72
  • 產(chǎn)品想暢銷須知工業(yè)設計的五大元素 好設計不等于好產(chǎn)品,好產(chǎn)品一般都能夠通過市場的考研肮柜,贏得市場獲得客戶的認可陷舅。工業(yè)...
    優(yōu)概念設計閱讀 799評論 0 4