亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

PDO防注入原理分析以及使用PDO的注意事項總結

2020-03-22 19:34:31
字體:
來源:轉載
供稿:網友
本文詳細講述了PDO防注入原理分析以及使用PDO的注意事項,分享給大家供大家參考。具體分析如下:我們都知道,只要合理正確使用PDO,可以基本上防止SQL注入的產生,本文主要回答以下兩個問題:
為什么要使用PDO而不是mysql_connect?
為何PDO能防注入?
使用PDO防注入的時候應該特別注意什么

一、為何要優先使用PDO PHP手冊上說得很清楚:
Prepared statements and stored procedures
Many of the more mature databases support the concept of prepared statements. What are they They can be thought of as a kind of compiled template for the SQL that an application wants to run, that can be customized using variable parameters. Prepared statements offer two major benefits: The query only needs to be parsed (or prepared) once, but can be executed multiple times with the same or different parameters. When the query is prepared, the database will analyze, compile and optimize its plan for executing the query. For complex queries this process can take up enough time that it will noticeably slow down an application if there is a need to repeat the same query many times with different parameters. By using a prepared statement the application avoids repeating the analyze/compile/optimize cycle. This means that prepared statements use fewer resources and thus run faster.
The parameters to prepared statements don't need to be quoted; the driver automatically handles this. If an application exclusively uses prepared statements, the developer can be sure that no SQL injection will occur (however, if other portions of the query are being built up with unescaped input, SQL injection is still possible).

即使用PDO的prepare方式,主要是提高相同SQL模板查詢性能、阻止SQL注入
同時,PHP手冊中給出了警告信息
Prior to PHP 5.3.6, this element was silently ignored. The same behaviour can be partly replicated with the PDO::MYSQL_ATTR_INIT_COMMAND driver option, as the following example shows.
Warning
The method in the below example can only be used with character sets that share the same lower 7 bit representation as ASCII, such as ISO-8859-1 and UTF-8. Users using character sets that have different representations (such as UTF-16 or Big5) must use the charset option provided in PHP 5.3.6 and later versions.

意思是說,在PHP 5.3.6及以前版本中,并不支持在DSN中的charset定義,而應該使用PDO::MYSQL_ATTR_INIT_COMMAND設置初始SQL, 即我們常用的 set names gbk指令。

我看到一些程序,還在嘗試使用addslashes達到防注入的目的,殊不知這樣其實問題更多, 詳情請看http://www.phpstudy.net/article/49205.htm
還有一些做法:在執行數據庫查詢前,將SQL中的select, union, ....之類的關鍵詞清理掉。這種做法顯然是非常錯誤的處理方式,如果提交的正文中確實包含 the students's union , 替換后將篡改本來的內容,濫殺無辜,不可取。

二、為何PDO能防SQL注入?
請先看以下PHP代碼:
復制代碼 代碼如下: php
$pdo = new PDO("mysql:host=192.168.0.1;dbname=test;charset=utf8","root");
$st = $pdo- prepare("select * from info where id = and name =

$id = 21;
$name = 'zhangsan';
$st- bindParam(1,$id);
$st- bindParam(2,$name);

$st- execute();
$st- fetchAll();


環境如下:
PHP 5.4.7
Mysql 協議版本 10
html' target='_blank'>MySQL Server 5.5.27

為了徹底搞清楚php與mysql server通訊的細節,我特別使用了wireshark抓包進行研究之,安裝wireshak之后,我們設置過濾條件為tcp.port==3306, 如下圖:



如此只顯示與mysql 3306端口的通信數據,避免不必要的干擾。
特別要注意的是wireshak基于wincap驅動,不支持本地環回接口的偵聽(即使用php連接本地mysql的方法是無法偵聽的),請連接其它機器(橋接網絡虛擬機也可)的MySQL進行測試。

然后運行我們的PHP程序,偵聽結果如下,我們發現,PHP只是簡單地將SQL直接發送給MySQL Server :



其實,這與我們平時使用mysql_real_escape_string將字符串進行轉義,再拼接成SQL語句沒有差別(只是由PDO本地驅動完成轉義的),顯然這種情況下還是有可能造成SQL注入的,也就是說在php本地調用pdo prepare中的mysql_real_escape_string來操作query,使用的是本地單字節字符集,而我們傳遞多字節編碼的變量時,有可能還是會造成SQL注入漏洞(php 5.3.6以前版本的問題之一,這也就解釋了為何在使用PDO時,建議升級到php 5.3.6+,并在DSN字符串中指定charset的原因。

針對php 5.3.6以前版本,以下代碼仍然可能造成SQL注入問題:
復制代碼 代碼如下:$pdo- query('SET NAMES GBK');
$var = chr(0xbf) . chr(0x27) . " OR 1=1 /*";
$query = "SELECT * FROM info WHERE name =
$stmt = $pdo- prepare($query);
$stmt- execute(array($var));

原因與上面的分析是一致的。

而正確的轉義應該是給mysql Server指定字符集,并將變量發送給MySQL Server完成根據字符轉義。

那么,如何才能禁止PHP本地轉義而交由MySQL Server轉義呢?
PDO有一項參數,名為PDO::ATTR_EMULATE_PREPARES ,表示是否使用PHP本地模擬prepare,此項參數默認值未知。而且根據我們剛剛抓包分析結果來看,php 5.3.6+默認還是使用本地變量轉,拼接成SQL發送給MySQL Server的,我們將這項值設置為false, 試試效果,如以下代碼:復制代碼 代碼如下: php
$pdo = new PDO("mysql:host=192.168.0.1;dbname=test;","root");
$pdo- setAttribute(PDO::ATTR_EMULATE_PREPARES, false);//這是我們剛加入的內容

$st = $pdo- prepare("select * from info where id = and name =
$id = 21;
$name = 'zhangsan';

$st- bindParam(1,$id);
$st- bindParam(2,$name);
$st- execute();
$st- fetchAll();


運行一下程序,使用wireshark抓包分析,得出的結果如下:看到了嗎?這就是神奇之處,可見這次PHP是將SQL模板和變量是分兩次發送給MySQL的,由MySQL完成變量的轉義處理,既然變量和SQL模板是分兩次發送的,那么就不存在SQL注入的問題了,但需要在DSN中指定charset屬性,如:
復制代碼 代碼如下:$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root');

如此,即可從根本上杜絕SQL注入的問題。如果你對此不是很清楚,可以發郵件至zhangxugg@163.com, 一起探討。

三、使用PDO的注意事項知道以上幾點之后,我們就可以總結使用PDO杜絕SQL注入的幾個注意事項:1. php升級到5.3.6+,生產環境強烈建議升級到php 5.3.9+ php 5.4+,php 5.3.8存在致命的hash碰撞漏洞。

2. 若使用php 5.3.6+, 請在在PDO的DSN中指定charset屬性3. 如果使用了PHP 5.3.6及以前版本,設置PDO::ATTR_EMULATE_PREPARES參數為false(即由MySQL進行變量處理),php 5.3.6以上版本已經處理了這個問題,無論是使用本地模擬prepare還是調用mysql server的prepare均可。在DSN中指定charset是無效的,同時set names charset 的執行是必不可少的。

4. 如果使用了PHP 5.3.6及以前版本, 因Yii框架默認并未設置ATTR_EMULATE_PREPARES的值,請在數據庫配置文件中指定emulatePrepare的值為false。

那么,有個問題,如果在DSN中指定了charset, 是否還需要執行set names charset 呢?是的,不能省。set names charset 其實有兩個作用:A. 告訴mysql server, 客戶端(PHP程序)提交給它的編碼是什么
B. 告訴mysql server, 客戶端需要的結果的編碼是什么也就是說,如果數據表使用gbk字符集,而PHP程序使用UTF-8編碼,我們在執行查詢前運行set names utf8, 告訴mysql server正確編碼即可,無須在程序中編碼轉換。這樣我們以utf-8編碼提交查詢到mysql server, 得到的結果也會是utf-8編碼。省卻了程序中的轉換編碼問題,不要有疑問,這樣做不會產生亂碼。

那么在DSN中指定charset的作用是什么 只是告訴PDO, 本地驅動轉義時使用指定的字符集(并不是設定mysql server通信字符集),設置mysql server通信字符集,還得使用set names charset 指令。

我真想不通,一些新的項目,為何不使用PDO而使用傳統的mysql_XXX函數庫呢?如果正確使用PDO,可以從根本上杜絕SQL注入,我強烈建議各個公司的技術負責人、一線技術研發人員,要對這個問題引起重視,盡可能使用PDO加快項目進度和安全質量。

不要再嘗試自己編寫SQL注入過濾函數庫了(又繁瑣而且很容易產生未知的漏洞)。希望本文所述對大家的PHP程序設計有所幫助。PHP教程

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
在线精品91av| 孩xxxx性bbbb欧美| 97超级碰在线看视频免费在线看| 97精品久久久| 久久视频免费观看| 最近2019中文字幕第三页视频| 亚洲精品aⅴ中文字幕乱码| 免费av一区二区| 久久精品视频在线观看| 欧美久久精品午夜青青大伊人| 国产精品女人网站| 在线观看久久av| 成人精品视频99在线观看免费| 亚洲精品一区中文字幕乱码| 91tv亚洲精品香蕉国产一区7ujn| 国产精品美女久久久免费| 亚洲字幕一区二区| 91免费人成网站在线观看18| 精品国产电影一区| 亚洲欧美国产高清va在线播| 国产亚洲欧美日韩一区二区| 亚洲激情 国产| 国产精品99久久久久久www| 久久影院资源网| 性色av一区二区三区红粉影视| 欧美精品videosex牲欧美| 日韩高清有码在线| 狠狠色狠狠色综合日日五| 激情av一区二区| 亚洲影院在线看| 国产91对白在线播放| 欧美人与性动交| 欧美日韩国产123| 亚洲无av在线中文字幕| 国产日韩中文在线| 亚洲国内高清视频| 波霸ol色综合久久| 91国产精品视频在线| 国产在线精品成人一区二区三区| 亚洲高清在线观看| 亚洲欧洲视频在线| 国产精品自产拍在线观看| 97超级碰在线看视频免费在线看| 国产91在线播放| 色悠悠国产精品| 日韩电影免费观看中文字幕| 亚洲精品美女久久久久| 疯狂做受xxxx欧美肥白少妇| 欧美日韩午夜剧场| 欧美精品久久久久久久| 91高清在线免费观看| 欧美噜噜久久久xxx| 国产91在线视频| 精品久久中文字幕| 奇门遁甲1982国语版免费观看高清| 亚洲美女免费精品视频在线观看| 国产成人精品在线视频| 精品国产一区二区在线| 欧美精品免费播放| 国产精品99久久久久久久久| 日本韩国欧美精品大片卡二| 九九久久久久99精品| 欧美成年人视频| 狠狠做深爱婷婷久久综合一区| 欧美一级片久久久久久久| 日韩中文字幕精品视频| 久久久久国产精品免费网站| 久久欧美在线电影| 国产日韩欧美91| 久久久最新网址| y97精品国产97久久久久久| 亚洲欧美日韩久久久久久| 国产精品高精视频免费| 亚洲欧美激情另类校园| 国语自产精品视频在线看抢先版图片| 日韩美女免费线视频| 日韩第一页在线| 国产一区香蕉久久| 曰本色欧美视频在线| 久久天天躁狠狠躁老女人| 亚洲欧美激情四射在线日| 国产精品久久久久久久久借妻| 日韩欧美极品在线观看| 7m第一福利500精品视频| 国产精品6699| 国产91ⅴ在线精品免费观看| 91精品国产高清| 久久免费视频这里只有精品| 色青青草原桃花久久综合| 欧美多人爱爱视频网站| 2018日韩中文字幕| 亚洲天堂av图片| 岛国av在线不卡| 国产成人精品一区二区| 97香蕉超级碰碰久久免费的优势| 中文字幕成人精品久久不卡| 欧美疯狂xxxx大交乱88av| 久久视频免费观看| 久久色免费在线视频| 俺去啦;欧美日韩| 欧美福利视频在线| 国产成人一区二区三区| 欧美电影在线观看网站| 懂色av影视一区二区三区| 深夜精品寂寞黄网站在线观看| 欧美大码xxxx| 亚洲欧洲xxxx| 91精品久久久久| 中文字幕亚洲第一| 精品亚洲aⅴ在线观看| 久久91精品国产91久久久| 欧美视频不卡中文| 亚洲xxxx3d| 青青久久av北条麻妃海外网| 日韩免费在线播放| 在线观看精品国产视频| 国产欧美一区二区三区在线看| 亚洲色图综合网| 91精品在线观| 久久天天躁狠狠躁夜夜爽蜜月| 一区二区欧美在线| 成人黄色中文字幕| 亲子乱一区二区三区电影| 亚洲成人性视频| 欧美国产日韩精品| 51久久精品夜色国产麻豆| 欧美日韩在线视频观看| 亚洲成人动漫在线播放| 中文字幕一区二区精品| 欧美大片在线影院| 91热精品视频| 日韩电影中文字幕一区| 亚洲网站视频福利| 国产精品欧美日韩一区二区| 综合国产在线视频| 日韩国产精品亚洲а∨天堂免| 欧美亚洲在线视频| 精品日本美女福利在线观看| 最近2019好看的中文字幕免费| 国产精品电影网| 久久九九免费视频| 午夜精品免费视频| 久久精品国产亚洲7777| 成人免费自拍视频| 97久久精品人人澡人人爽缅北| 亚洲国产日韩欧美在线99| 国产精品久久电影观看| 国产精品香蕉在线观看| 亚洲精品白浆高清久久久久久| 精品无人国产偷自产在线| 国产乱人伦真实精品视频| 欧美成人在线免费视频| 国产精品av电影| 欧美高清视频在线播放| 国内精品小视频在线观看| 久久久人成影片一区二区三区| 亚洲aaa激情| 亚洲综合大片69999| 色综合久久悠悠| 成人免费视频a| 亚洲欧美在线第一页| 热久久这里只有| 日韩国产欧美精品在线| 国产免费观看久久黄|