今天就跟大家聊聊有關(guān)MySQL注入在PHP代碼層面的防御手段是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡(jiǎn)單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:申請(qǐng)域名、網(wǎng)絡(luò)空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、松北網(wǎng)站維護(hù)、網(wǎng)站推廣。
什么是sql注入?
服務(wù)端沒有對(duì)用戶提交的參數(shù)進(jìn)行嚴(yán)格的過濾,導(dǎo)致可以將SQL語句插入到可控參數(shù)中,改變?cè)械腟QL語義結(jié)構(gòu),從而執(zhí)行攻擊者所預(yù)期的結(jié)果。
sql注入的探測(cè)
判斷數(shù)據(jù)庫類型
端口
報(bào)錯(cuò)信息
一些中間件常用的數(shù)據(jù)庫
PHP MySQL
ASP SQL Server
ASPX SQL Server
JSP MySQL Oracle
尋找SQL注入點(diǎn)
尋找與數(shù)據(jù)庫交互的可控參數(shù)
GET
POST
COOKIE
HTTP頭
確定注入點(diǎn)
確定注入點(diǎn)的核心思想就是判斷插入的數(shù)據(jù)是否被當(dāng)做SQL語句執(zhí)行??梢允褂煤?jiǎn)單的算術(shù)運(yùn)算來測(cè)試。
SQL語句預(yù)編譯和綁定變量
使用足夠嚴(yán)格的過濾和安全防御
Web應(yīng)用向數(shù)據(jù)庫傳遞語句模板
數(shù)據(jù)庫對(duì)模板進(jìn)行編譯,編譯以后語義將不會(huì)改變
變量綁定,Web應(yīng)用向數(shù)據(jù)庫傳遞變量,變量只會(huì)被當(dāng)做數(shù)據(jù)識(shí)別,不會(huì)被作為語義結(jié)構(gòu)識(shí)別
執(zhí)行SQL語句
SQL注入的核心:數(shù)據(jù)和代碼的混淆。
什么是PDO?
PHP 數(shù)據(jù)對(duì)象 (PDO) 擴(kuò)展為PHP訪問數(shù)據(jù)庫定義了一個(gè)輕量級(jí)的一致接口。
PDO 提供了一個(gè)數(shù)據(jù)訪問抽象層,這意味著,不管使用哪種數(shù)據(jù)庫,都可以用相同的函數(shù)(方法)來查詢和獲取數(shù)據(jù)。
PDO是php中最典型的預(yù)編譯查詢方式。
PDO場(chǎng)景下的SQL注入
PDO與安全相關(guān)的問題主要的設(shè)置有下面三項(xiàng):
PDO::ATTR_EMULATE_PREPARES # 模擬預(yù)編譯 PDO::ATTR_ERRMODE # 報(bào)錯(cuò) PDO::MYSQL_ATTR_MULTI_STATEMENTS # 多語句執(zhí)行
第一項(xiàng)為模擬預(yù)編譯,如果為False,則不存在SQL注入;如果為True,則PDO并非真正的預(yù)編譯,而是將輸入統(tǒng)一轉(zhuǎn)化為字符型,并轉(zhuǎn)義特殊字符。這樣如果是gbk編碼則存在寬字節(jié)注入。
第二項(xiàng)而報(bào)錯(cuò),如果設(shè)置為True,可能會(huì)泄露一些信息。
第三項(xiàng)為多語句執(zhí)行,如果設(shè)置為True,且第一項(xiàng)也為True,則會(huì)存在寬字節(jié)+堆疊注入的雙重漏洞。
對(duì)于此類問題的防范,主要有以下三個(gè)方面:
合理、安全的使用gbk編碼。即使采用PDO預(yù)編譯的方式,如果開啟模擬預(yù)編譯,依然可以造成寬字節(jié)注入。
使用PDO時(shí),一定要將模擬預(yù)編譯設(shè)置為false。
可采用Prepare Statement手動(dòng)預(yù)編譯,防御SQL注入。
代碼示例
$dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password); $stmt = $dbh->prepare('INSERT INTO REGISTRY (name, value) VALUES (:name, :value)'); $stmt->bindParam(':name', $name); $stmt->bindParam(':value', $value); // insert one row $name = 'one'; $value = 1; $stmt->execute();
或者
$dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password); $stmt = $dbh->prepare('UPDATE people SET name = :new_name WHERE id = :id'); $stmt->execute( array('new_name' => $name, 'id' => $id) );
詳細(xì)請(qǐng)參考:
從寬字節(jié)注入認(rèn)識(shí)PDO的原理和正確使用
SQL注入基礎(chǔ)整理及Tricks總結(jié)
技術(shù)分享 | MySQL 注入攻擊與防御
ODBC 是一種應(yīng)用程序編程接口(Application Programming Interface,API),使我們有能力連接到某個(gè)數(shù)據(jù)源(比如一個(gè) MS Access 數(shù)據(jù)庫)。
代碼示例
$stmt = odbc_prepare( $conn, 'SELECT * FROM users WHERE email = ?' ); $success = odbc_execute( $stmt, array($email) );
或者
$dbh = odbc_exec($conn, 'SELECT * FROM users WHERE email = ?', array($email)); $sth = $dbh->prepare('SELECT * FROM users WHERE email = :email'); $sth->execute(array(':email' => $email));
MySQLi函數(shù)允許你訪問MySQL數(shù)據(jù)庫服務(wù)器。
$stmt = $db->prepare('update name set name = ? where id = ?'); $stmt->bind_param('si',$name,$id); $stmt->execute();
對(duì)于框架的話只要遵循框架的API就好,例如wp查詢
global $wpdb; $wpdb->query( $wpdb->prepare( 'SELECT name FROM people WHERE id = %d OR email = %s', $person_id, $person_email ) );
global $wpdb; $wpdb->insert( 'people', array( 'person_id' => '123', 'person_email' => 'bobby@tables.com' ), array( '%d', '%s' ) );
看完上述內(nèi)容,你們對(duì)mysql注入在PHP代碼層面的防御手段是什么有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。