最近關于php 5.2.17存在漏洞的新聞引起了廣泛的關注和熱議。這個漏洞可以被黑客用來執行SQL注入攻擊,進而獲取網站的敏感信息或篡改網站的內容。這個漏洞的危害性非常高,而且已經被大量黑客利用。
那么這個漏洞是如何產生的呢?其實在php 5.2.17里面存在一個叫做mysql_real_escape_string()函數的漏洞,這個函數的作用是將用戶輸入的字符串中的特殊字符轉義后再傳給mysql數據庫。但是在這個函數的實現中,由于一些設計問題,導致了這個轉義過程不夠嚴格,從而使得惡意用戶可以通過一些特定的輸入來繞過轉義過程,達到注入攻擊的目的。
// 這是mysql_real_escape_string的源碼(php 5.2.17版本) function mysql_real_escape_string($string, $link_identifier = NULL) { $trans = array("\0" =>"\\0", "\n" =>"\\n", "\r" =>"\\r", "\\" =>"\\\\", "'" =>"\\'", "\"" =>"\\\""); return strtr($string, $trans); }
我們來看一個具體的例子,假設我們的網站有一個搜索功能,用戶輸入一個商品名稱,網站后臺會把這個名稱傳給mysql數據庫執行查詢操作。但是我們的惡意用戶在搜索框中輸入了如下內容:
1\\\' or \\\'1\\\'=\\\'1
在經過mysql_real_escape_string()的處理后,這個輸入被轉義為:
1\\\\\\' or \\\\'1\\\\\\'=\\\\\\'1
然后這個字符串被傳給mysql數據庫,當數據庫執行查詢操作時,由于\\\被轉義為\\,'被轉義為\',所以最終執行的查詢語句如下:
SELECT * FROM products WHERE name LIKE '1\\\\\\'\'' or \\\\'1\\\\\\'=\\\\\\'1'
這條查詢語句的意思是找到所有名字中包含1\\'或者1=1的商品,由于1=1是恒成立的,所以這個查詢相當于找到了商品表中的所有商品,完成了注入攻擊。
為了避免這個漏洞的出現,我們需要使用更加嚴格的轉義函數,例如mysqli_real_escape_string()。當然更好的辦法是升級php版本至5.3以上,這個版本的mysql_real_escape_string()已經修復了這個漏洞。
// 這是mysqli_real_escape_string的源碼(php 5.5.9版本) function mysqli_real_escape_string($link, $string) { return mysqli::real_escape_string($link, $string); }
總之,php 5.2.17漏洞的存在給我們的網站帶來了嚴重的安全隱患,我們需要及時進行修復。同時,在寫代碼時也要特別注意字符串的轉義和安全性檢查,避免類似的漏洞再次出現。