您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關mysql注入在PHP代碼層面的防御手段是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
什么是sql注入?
服務端沒有對用戶提交的參數進行嚴格的過濾,導致可以將SQL語句插入到可控參數中,改變原有的SQL語義結構,從而執行攻擊者所預期的結果。
sql注入的探測
判斷數據庫類型
端口
報錯信息
一些中間件常用的數據庫
PHP MySQL
ASP SQL Server
ASPX SQL Server
JSP MySQL Oracle
尋找SQL注入點
尋找與數據庫交互的可控參數
GET
POST
COOKIE
HTTP頭
確定注入點
確定注入點的核心思想就是判斷插入的數據是否被當做SQL語句執行。可以使用簡單的算術運算來測試。
SQL語句預編譯和綁定變量
使用足夠嚴格的過濾和安全防御
Web應用向數據庫傳遞語句模板
數據庫對模板進行編譯,編譯以后語義將不會改變
變量綁定,Web應用向數據庫傳遞變量,變量只會被當做數據識別,不會被作為語義結構識別
執行SQL語句
SQL注入的核心:數據和代碼的混淆。
什么是PDO?
PHP 數據對象 (PDO) 擴展為PHP訪問數據庫定義了一個輕量級的一致接口。
PDO 提供了一個數據訪問抽象層,這意味著,不管使用哪種數據庫,都可以用相同的函數(方法)來查詢和獲取數據。
PDO是php中最典型的預編譯查詢方式。
PDO場景下的SQL注入
PDO與安全相關的問題主要的設置有下面三項:
PDO::ATTR_EMULATE_PREPARES # 模擬預編譯
PDO::ATTR_ERRMODE # 報錯
PDO::MYSQL_ATTR_MULTI_STATEMENTS # 多語句執行
第一項為模擬預編譯,如果為False,則不存在SQL注入;如果為True,則PDO并非真正的預編譯,而是將輸入統一轉化為字符型,并轉義特殊字符。這樣如果是gbk編碼則存在寬字節注入。
第二項而報錯,如果設置為True,可能會泄露一些信息。
第三項為多語句執行,如果設置為True,且第一項也為True,則會存在寬字節+堆疊注入的雙重漏洞。
對于此類問題的防范,主要有以下三個方面:
合理、安全的使用gbk編碼。即使采用PDO預編譯的方式,如果開啟模擬預編譯,依然可以造成寬字節注入。
使用PDO時,一定要將模擬預編譯設置為false。
可采用Prepare Statement手動預編譯,防御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) );
詳細請參考:
從寬字節注入認識PDO的原理和正確使用
SQL注入基礎整理及Tricks總結
技術分享 | MySQL 注入攻擊與防御
ODBC 是一種應用程序編程接口(Application Programming Interface,API),使我們有能力連接到某個數據源(比如一個 MS Access 數據庫)。
代碼示例
$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函數允許你訪問MySQL數據庫服務器。
$stmt = $db->prepare('update name set name = ? where id = ?');
$stmt->bind_param('si',$name,$id);
$stmt->execute();
對于框架的話只要遵循框架的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' )
);
看完上述內容,你們對mysql注入在PHP代碼層面的防御手段是什么有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。