PDO防止sql注入的原理


 

  首先,PDO可以被認作是一種通過編譯SQL語句模板來運行sql語句的機制。

  預處理語句可以帶來兩大好處:

 1.查詢只需要被解析(或編譯)一次,但可以執行多次通過相同或不同的參數。當查詢處理好后,數據庫將分析,編譯和優化它的計划來執行查詢。對於復雜的查詢這個過程可能需要足夠的時間,這將顯著地使得應用程序變慢,如果有必要,可以多次使用不同的參數 重復相同的查詢。通過使用處理好的語句的應用程序避免重復 【分析/編譯/優化】 周期。這意味着,預處理語句使用更少的資源,而且運行得更快。

 2.綁定的參數不需要使用引號;該驅動程序會自動處理。如果應用程序使用預處理語句,開發人員可以確保不會發生SQL注入(但是,如果查詢的其他部分使用了未轉義的輸入,SQL注入仍然是可能的)。

  預處理語句非常有用,PDO可以使用一種本地模擬的辦法來為沒有預處理功能的數據庫系統提供這個功能。這保證了一個應用可以使用統一的訪問方式來訪問數據庫。

  使用PDO可以帶來兩個很好的效果,預編譯帶來查詢速度的提升,變量的綁定可以預防 sql injection,其實PDO的預防sql注入的機制也是類似於使用 mysql_real_escape_string 進行轉義。

  PDO 有兩種轉義的機制:

  (1)第一種是本地轉義,這種轉義的方式是使用單字節字符集(PHP < 5.3.6)來轉義的( 單字節與多字節 ),來對輸入進行轉義,但是這種轉義方式有一些 隱患 。隱患主要是:在PHP版本小於5.3.6的時候,本地轉義只能轉換單字節的字符集,大於 5.3.6 的版本會根據 PDO 連接中指定的 charset 來轉義。PHP官方手冊這里有 說明 :

  不同的版本的PDO 在本地轉義的行為上是有區別的。

  (2)第二種方式是PDO,首先將 sql 語句模板發送給Mysql Server,隨后將綁定的字符變量再發送給Mysql server,這里的轉義是在Mysql Server做的,它是根據你在連接PDO的時候,在charset里指定的編碼格式來轉換的。這樣的轉義方式更健全,同時還可以在又多次重復查詢的業務場景下,通過復用模板,來提高程序的性能。如果要設置Mysql Server  來轉義的話,就要首先執行:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

綁定的變量:



如果不執行  $pdo ->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); PDO 只是會將插入的參數使用本地轉義之后和SQL模板拼裝起來,然后一起發送給Mysql Server。這實際上與使用mysql_real_escape_string()過濾,然后拼裝這種做法並沒有什么不同。

要對數據庫的安全做出更加全面的考量,以下兩種方式任選其一:

A. 通過添加(php 5.3.6以前版本):$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

B.  升級到php 5.3.6 (不用設置PDO::ATTR_EMULATE_PREPARES也可以)

為了程序移植性和統一安全性,建議使用$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false)方法

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM