sql注入方式及如何有效避免

首先說起sql注入這個題目,也許你們會笑笑,以爲這是一件比較低級的攻擊方式,但事實上,正是這種不屑,就可能會致使咱們網站數據庫服務器被攻擊,甚至服務器權限都被提走,這種例子,以不鮮見。如下是我在寫ORM時sql注入這塊,所研究的心得,分享給你們,有可能說的不對,還望你們指正。
 
先來看下這段sql
$query = 'SELECT * from user where name =" '.$name.' "';
這樣的sql是咱們常常有寫的,
 
而後$name = ' ";delete from user where name="mini -- ";';
這裏' 後面跟一個空格,其實沒有,是wile看的更清楚些
 
如此,這就是是一個sql注入,先截斷了咱們定義好的"符號,自定義一個"使之於咱們定義好的第一個"配對,這樣後面的輸入串,就非一個sql字符串了,就成功完成sql注入
 
這種截斷引號的注入方式很是常見,固然引號包括單引號於雙引號,注入者,必需要完成與sql語句的前一個引號,成功配對,纔可能完成注入,這裏所說的成功配置指的是,若是 咱們這裏
where name =" ' .$name. ' " 注入者,就必須只有用"號才能成功配對,截斷本該是字符串的參數,
若是這塊是 where name =' " .$name. " ' 單引號來標識的字符串,那麼注入者,只可能用單引號來截斷,完成注入
 
注意上面提到的sql語句,變量拼接語法所涉及到的單引號或雙引號,這只是語法形式,拼接完成後,並不會保留
 
前面說到的是,截斷引號方式的注入方法,還有一種是根本不須要截斷引號就能夠完成注入的方式,
好比說,以下sql 
 
 $query = 'SELECT * from '.$user.' where name ="zhangyan" ';
 
其中$user = 'user;delete from user where name="mini";--';
 
如此這個變量原本就不在一個字符串中,固然,注入時,不用引號配對來截斷,直接;結束上一個sql而後寫咱們的注入sql語句就ok
 
因此,有效的避免sql注入,並不只僅是在where條件後。
 
如何來有效的避免sql注入呢,
 
這裏只說pdo,
 
 
1.首先pdo提供quote方法,來轉義全部的輸入的參數
 
可是使用quote方法須要注意的是,它認爲全部輸入的參數都是字符串形式輸出,因此在拼接sql是,自定義的sql語句就不用在加上 字符串表示符了(單引號或者雙引號) 好比說where name ='.$name 
直接如此就ok 。這裏出現的單引號是爲了拼接變量的語法形式,並非字符串中的引號
 
2.第二種方式是使用prepare來於執行你的sql語句,以後再進行填充你的輸入參數,以此來保證不會出現截斷總體sql的行爲,但並非說sql語句就徹底可以防止sql注入,好比以下
 
$prepareSql = 'SELECT * from '.$user.' where name =:name';
$sth = $dbh->prepare($prepareSql);
$sth->execute(array(':name' => 'zhangsan'));
 
這裏的$user 仍是和以前同樣 $user = 'user;delete from user where name="mini";--';
 
這樣在預執行的時候,sql注入就已經發生了,網上都說pdo可以防止sql注入,這徹底是不對的說法,
 
實際上是否能徹底防止sql語句,在於你是怎樣用 的,好比說,咱們把全部的輸入參數,都通過轉義後,才拼接到sql語句中,若是是用prepare,咱們把全部輸入參數都放在execute中,而不是拼接在prepare時,如此就能有效的防範sql注入,
 
其實關於網上說pdo可以防止sql注入,這句話應該這樣說,pdo可以提供給更好的方法來防止sql注入。
 
其餘連接數據庫方式,只要作好輸入字段的轉義工做,也同樣可以有效的防止sql的注入
 
其實所謂字段的轉義工做,在sql語句裏面,能夠參照於pdo的quote方法,吧全部輸入字段都當作字符串的輸出,而且對全部引號進行轉義,這樣就能有效的防止,sql語句的注入。
 
 
3.對整個sql語句進行直接轉義。
 
也許你回這樣想,直接對整個sql語句進行轉義,這樣就開發者就不用單獨提出所輸入的字段了,也許你沒這樣想過,但至少我這樣想過,可是這種方式是不對的,以下
 
這裏就不以腳本的形式表現了,直接是sql語句形式
SELECT * from user where name = /"zh/"angyan/"
 
若是是對整個sql語句進行直接轉義,最終發送給mysql的就是這樣一句sql。
 
能夠執行下,就知道,失敗。
由於第一次轉義和第二次轉義的",正好會完成引號的配對,這樣後面的字符就不是一種字符串方式了,在此以前,sql語句已經被截斷,也就是說這種方式,是不會解決sql注入的。
 
最後總結一句:想從根本上解決sql注入,其實在於開發者的我的意識,根本上說什麼框架不能完美的解決這個問題,即便是從框架方法解決,開發者也必需要把輸入數據按照框架的約定放在我特定的規則裏面,才能完美的解決sql注入隱患。
相關文章
相關標籤/搜索