php sql注入與防注入經典案例分析

來源:互聯網
上載者:User

一個簡單的SQL注入攻擊案例
假如我們有一個公司網站,在網站的後台資料庫中儲存了所有的客戶資料等重要訊息。假如網站登入頁面的代碼中有這樣一條命令來讀取使用者資訊。

 代碼如下 複製代碼

<?

$q = "SELECT `id` FROM `users` WHERE `username`= ' " .$_GET['username']. " ' AND `password`= ' " .$_GET['password']. " ' ";

?>

現在有一個駭客想攻擊你的資料庫,他會嘗試在此登入頁面的使用者名稱的輸入框中輸入以下代碼:

 代碼如下 複製代碼

' ; SHOW TABLES;

點擊登陸鍵,這個頁面就會顯示出資料庫中的所有表。如果他現在使用下面這行命令:

 代碼如下 複製代碼

'; DROP TABLE [table name];

這樣他就把一張表刪除了!

當然,這隻是一個很簡單的例子,實際的SQL注入方法比這個要複雜得多,駭客也願意花大量的時間來不斷嘗試來攻擊你的代碼。有一些程式軟體也可以自動地來不斷嘗試SQL注入攻擊。瞭解了SQL注入的攻擊原理後,我們來看一下如何防範SQL注入攻擊。

magic_quotes_gpc = On 時的注入攻擊
  當 magic_quotes_gpc = On 時,攻擊者無法對字元型的欄位進行 SQL 注入。這並不代表這就安全了。這時,可以通過數值型的欄位進行SQL注入。

  在最新版的 MYSQL 5.x 中,已經嚴格了資料類型的輸入,已預設關閉自動類型轉換。數值型的欄位,不能是引號標記的字元型。也就是說,假設 uid 是數值型的,在以前的 mysql 版本中,這樣的語句是合法的:

 代碼如下 複製代碼

INSERT INTO tbl_user SET uid="1";
SELECT * FROM tbl_user WHERE uid="1";

  在最新的 MYSQL 5.x 中,上面的語句不是合法的,必須寫成這樣:

 代碼如下 複製代碼

INSERT INTO tbl_user SET uid=1;
SELECT * FROM tbl_user WHERE uid=1;

  這樣我認為是正確的。因為作為開發人員,向資料庫提交正確的符合規則的資料類型,這是最基本的要求。

  那麼攻擊者在 magic_quotes_gpc = On 時,他們怎麼攻擊呢?很簡單,就是對數值型的欄位進行 SQL 注入。以下列的 php 指令碼為例:

 代碼如下 複製代碼

<?
if ( isset($_POST["f_login"] ) )
{
  // 串連資料庫...
  // ...代碼略...
 
  // 檢查使用者是否存在
  $t_strUid = $_POST["f_uid"];
  $t_strPwd = $_POST["f_pwd"];
  $t_strSQL = "SELECT * FROM tbl_users WHERE uid=$t_strUid AND password = '$t_strPwd' LIMIT 0,1";
  if ( $t_hRes = mysql_query($t_strSQL) )
  {
    // 成功查詢之後的處理. 略...
  }

}
?>
<html><head><title>sample test</title></head>
<body>
<form method=post action="">
  User ID: <input type="text" name="f_uid" size=30><br>

  Password: <input type=text name="f_pwd" size=30><br>
  <input type="submit" name="f_login" value="登入">
</form>
</body>


  上面這段指令碼要求使用者輸入 userid 和 password 登入。一個正常的語句,使用者輸入 1001和abc123,提交的 sql 語句如下:

 代碼如下 複製代碼
SELECT * FROM tbl_users WHERE userid=1001 AND password = 'abc123' LIMIT 0,1

  如果攻擊者在 userid 處,輸入:1001 OR 1 =1 #,則注入的sql語句如下:

 代碼如下 複製代碼
SELECT * FROM tbl_users WHERE userid=1001 OR 1 =1 # AND password = 'abc123' LIMIT 0,1

  攻擊者達到了目的。

 

防範SQL注入 - 使用mysql_real_escape_string()函數

在資料庫操作的代碼中用這個函數mysql_real_escape_string()可以將代碼中特殊字元過濾掉,如引號等。如下例:

 代碼如下 複製代碼

<?

$q = "SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`= ' " .mysql_real_escape_string( $_GET['password'] ). " ' ";

?>

防範SQL注入 - 使用mysql_query()函數

mysql_query()的特別是它將只執行SQL代碼的第一條,而後面的並不會執行。回想在最前面的例子中,駭客通過代碼來例後台執行了多條SQL命令,顯示出了所有表的名稱。所以mysql_query()函數可以取到進一步保護的作用。我們進一步演化剛才的代碼就得到了下面的代碼:

 代碼如下 複製代碼

<?

//connection
$database = mysql_connect("localhost", "username","password");

//db selection
mysql_select_db("database", $database);

$q = mysql_query("SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`= ' " .mysql_real_escape_string( $_GET['password'] ). " ' ", $database); 

?>

除此之外,我們還可以在PHP代碼中判斷輸入值的長度,或者專門用一個函數來檢查輸入的值。所以在接受使用者輸入值的地方一定要做好輸入內容的過濾和檢查。當然學習和瞭解最新的SQL注入方式也非常重要,這樣才能做到有目的的防範。如果使用的是平台式的網站系統如Wordpress,要注意及時打上官方的補丁或升級到新的版本。如果有講得不對的地方或不理解的請在評論區留言。

php.ini 中的 display_errors 選項,應該設為 display_errors = off。這樣 php 指令碼出錯之後,不會在 web 頁面輸出錯誤,以免讓攻擊者分析出有作的資訊。
調用 mysql_query 等 mysql 函數時,前面應該加上 @,即 @mysql_query(...),這樣 mysql 錯誤不會被輸出。同理以免讓攻擊者分析出有用的資訊。另外,有些程式員在做開發時,當 mysql_query出錯時,習慣輸出錯誤以及 sql 語句,例如:

 代碼如下 複製代碼
$t_strSQL = "SELECT a from b....";
if ( mysql_query($t_strSQL) )
{
  // 正確的處理
}
else
{
  echo "錯誤! SQL 陳述式:$t_strSQL rn錯誤資訊".mysql_query();
  exit;
}

  這種做法是相當危險和愚蠢的。如果一定要這麼做,最好在網站的設定檔中,設一個全域變數或定義一個宏,設一下 debug 標誌:

全域設定檔中:

 代碼如下 複製代碼
define("DEBUG_MODE",0); // 1: DEBUG MODE; 0: RELEASE MODE

//呼叫指令碼中:

 代碼如下 複製代碼
$t_strSQL = "SELECT a from b....";
if ( mysql_query($t_strSQL) )
{
  // 正確的處理
}
else
{
  if (DEBUG_MODE)
    echo "錯誤! SQL 陳述式:$t_strSQL rn錯誤資訊".mysql_query();
  exit;
}


關於 sql防注入內容 http://www.111cn.net/phper/phpanqn/37704.htm

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.