mysql 之sql注入詳解

來源:互聯網
上載者:User

標籤:mysql sql

SQL 注入( SQL Injection )攻擊是發生在應用程式中的資料庫層的安全性漏洞。簡而言之,是在輸入的字串之中注入 SQL 陳述式,如果在設計不良的程式中忽略了檢查,那麼這些注入進去的 SQL 陳述式就會被資料庫伺服器誤認為是正常的 SQL 陳述式而運行,攻擊者就可以執行計畫外的命令或訪問未被授權的資料。 SQL 注入已經成為互連網世界 Web 應用程式的最大風險。我們有必要從開發、測試、上線各個環節對其進行防範。以下將介紹 SQL 注入的原理及如何預防 SQL 注入。

SQL 注入的原理有如下 4 點

1 )拼接惡意查詢。 SQL 命令可查詢、插入、更新、刪除資料,以分號字元分隔不同的命令。

例如:

select * from users where user_id = $user_id

user_id 是傳入的參數,如果傳入了 “1234;delete from users” ,那麼最終的查詢語句會變為:

select * from users where user_id = 1234; delete from users

如上語句如果執行,則會刪除 user 表的資料。

2 )利用注釋執行非法命令。 SQL 命令中,可以插入注釋。

例如:

select count(*) as ‘num‘ from game_score where game_id=24411 and platform_id=11 and version=$version and session_id =

sessid=‘d7a157-0f-48b6-98-c35592‘

如果 version 包含了惡意的字串 “‘-1‘OR 3 AND SLEEP(500)--” ,那麼最終查詢語句會變成下面這個樣子:

select count(*) as ‘num‘ from game_score where game_id=24411 and platform_id=11 and version=‘-1‘ OR 3 AND SLEEP(500)-- ‘

and session_id = sessid=‘d7a157-0f-48b6-98-c35592‘

以上惡意查詢只是想耗盡系統資源, SLEEP(500) 將導致 SQL 一直運行,如果添加了修改、刪除資料的惡意指令,將會造成

更大的破壞。

3 ) SQL 命令對於傳入的字串參數是用單引號引起來的。如果字串本身包含單引號而沒有被處理,則可能會篡改原本

的 SQL 文法的作用。

例如:

select * from user_name where user_name = $user_name

如果 user_name 傳入的是 G‘chen ,那麼最終的查詢語句會變成這樣:

select * from user_name where user_name =‘G‘chen‘

以上語句將會出錯,這樣的語句風險比較小,因為語法錯誤的 SQL 陳述式不會被執行。但也可能惡意產生的 SQL 陳述式,沒有

任何語法錯誤,並且以一種你不期望的方式運行。

4 )添加一些額外的條件為真值運算式,改變執行行為。

例如:

update users set userpass=SHA2(‘$userpass‘) where user_id=$user_id;

如果 user_id 被傳入惡意的字串 “1234 OR TRUE” ,最終的 SQL 陳述式會變成下面這樣:

update users set userpass=SHA2(‘123456‘) where user_id=1234 OR TRUE;

這將更改所有使用者的密碼。

下面是避免 SQL 注入的一些方法。

( 1 )過濾輸入內容,校正字串

應該在將資料提交到資料庫之前,就把使用者輸入中的不合法字元剔除掉。可以使用程式設計語言提供的處理函數,如 PHP 的

mysql_real_escape_string() 來剔除,或者定義自己的處理函數進行過濾,還可以使用Regex匹配安全的字串。

如果值屬於特定的類型或有約定的格式,那麼在拼接 SQL 陳述式之前就要進行校正,驗證其的有效性。比如對於某個傳入的

值,如果可以確定是整型,那麼我們要判斷下它是否為整型,不僅在瀏覽器端(用戶端),而且在伺服器端也需要進行驗證。

( 2 )參數化查詢

參數化查詢目前已被視作是最有效預防 SQL 插入式攻擊的方法。不同於在 SQL 陳述式中插入動態內容,查詢參數的做法是在

準備查詢語句的時候,就在對應參數的地方使用參數預留位置。然後,在執行這個預先準備好的查詢時提供一個參數。

在使用參數化查詢的情況下,資料庫伺服器不會將參數的內容視為 SQL 指令的一部分來進行處理,而是在資料庫完成 SQL

指令的編譯之後,才套用參數運行,因此就算參數中含有破壞性的指令,也不會被資料庫所運行。

可以使用 MySQLi 擴充或 pdo 擴充來綁定參數實現參數化查詢。

如下是一個使用 MySQLi 擴充綁定參數的樣本。

<html>

<head>

<title> test parameter query </title>

</head>

<body>

<?php

$host="127.0.0.1";

$port=3306;

$socket="";

$user="garychen";

$password="garychen";

$dbname="employees";

$con = new mysqli($host, $user, $password, $dbname, $port, $socket)

or die (‘Could not connect to the database server‘ . mysqli_connect_error());

echo ‘connect to employees database successfully‘;

echo "<br />";

echo "select departments table using parameter";

echo "<br />";

$query = "select * from departments where dept_name = ?";

if ($stmt = $con->prepare($query)) {

$stmt->bind_param("s",$depname);

$depname="Finance";

$stmt->execute();

$stmt->bind_result($field1, $field2);

while ($stmt->fetch()) {

printf("%s, %s\n", $field1, $field2);

echo "<br />";

}

$stmt->close();

}

$con->close();

?>

</body>

</html>

上例首先是預先處理語句 if($stmt=$con->prepare($query)) ,然後綁定參數使用 bind_param() 方法,該方法的文法格式如下所示。

bool mysqli_stmt::bind_param ( string $types , mixed &$var1 [, mixed &$... ] )

其中, types 指定綁定參數的類型,包含了一個或多個字元。 I 代表整型, D 代表雙精確度, S 代表字串, B 代表 BLOB 類型,

本例中是 S 。

但是綁定參數也有如下一些限制。

· 不能讓預留位置 “?” 代替一組值,例如:

SELECT * FROM departments WHERE userid IN ( ? );

· 不能讓預留位置 “?” 代替資料表名或列名,例如:

SELECT * FROM departments ORDER BY ?;

· 不能讓預留位置 “?” 代替 SQL 關鍵字,例如:

SELECT * FROM departments ORDER BY dept_no ?;

對於 Java 、 JSP 開發的應用,也可以使用預先處理語句加綁定參數的方式來避免 SQL 注入。

( 3 )安全性測試、安全審計

除了開發規範,還需要流程、機制和合適的工具來確保代碼的安全。我們應該在開發過程中對代碼進行審查,在測試環節

使用工具進行掃描,上線後定期掃描安全性漏洞。通過多個環節的檢查,一般是可以避免 SQL 注入的。

有些人認為預存程序可以避免 SQL 注入,預存程序在傳統行業裡用得比較多,對於許可權的控制是有一定用處的,但如果存

儲過程用到了動態查詢,拼接 SQL ,那就一樣會存在安全隱患。一些編程架構對於寫出更安全的代碼也有一定的協助,因為它

提供了一些處理字串的函數和使用查詢參數的方法,但同樣,你仍然可以編寫出不安全的 SQL 陳述式。所以歸根到底

摘自MySQLDBA修鍊之道

本文出自 “大李子” 部落格,謝絕轉載!

mysql 之sql注入詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.