以php語言為例,概述編碼過程中的sql注入過程,注入可能涉及 存儲過程 、sql語句、關鍵字等方式,本篇只介紹sql相關。

注入基本原理
  1. (正常情況)假設我們可以通過 http://localhost/test/userinfo.php?username=plhwin 這個URL來訪問到具體某個會員的詳情,正常情況下,如果瀏覽器里傳入的username是合法的,那麼SQL語句會執行:
    SELECT uid,username FROM user WHERE username='plhwin'
  2. (注入情況)但是,如果用戶在瀏覽器里把傳入的username參數變為 plhwin’;SHOW TABLES– hack,也就是當URL變為 http://localhost/test/userinfo.php?username=plhwin’;SHOW TABLES– hack 的時候,此時我們程序實際執行的SQL語句變成了:
    SELECT uid,username FROM user WHERE username='plhwin';SHOW TABLES-- hack'
解決辦法
  1. 先說一個線上服務器的配置.
    比如用PHP,php.ini文件中的錯誤提示開關等一定要在生產環境關掉,可百度下,此處不講。(一般雲服務器已經做好了這個)
  2. 普通用戶與系統管理員用戶的權限要有嚴格的區分。
    即對普通訪問用戶只有查詢等最低使用權限,並對不同管理人員進行區分,比如root用戶、啟停用戶、管理用戶、應用用戶等

  3. 強迫使用參數化語句。如下面的寫法

    $sql = "SELECT * FROM table WHERE username = ? AND pwd = ?";    
    bindParam($sql, 1, $username, 'STRING');  
    //以字符串的形式.在第一個問號的地方綁定$username這個變量    
    bindParam($sql, 2, $pwd, 'STRING');       
    //以字符串的形式.在第二個問號的地方綁定$pwd這個變量
  4. 過濾特殊符號以及檢查變量數據類型等
    $uid = isset($_GET['uid']) ? $_GET['uid'] : 0;
    $uid = addslashes(uid);
    $sql = "SELECT uid,username FROM user WHERE uid='{$uid}'";
    $uid = isset($_GET['uid']) ? $_GET['uid'] : 0;
    $uid = addslashes(uid);
    $sql = "SELECT uid,username FROM user WHERE uid={$uid}";

    上面兩個查詢語句都經過了php的addslashes函數過濾轉義,但在安全性上卻大不相同,在MySQL中,對於int類型字段的條件查詢,上面個語句的查詢效果完全一樣,由於第一句SQL的變量被單引號包含起來,SQL注入的時候,黑客面臨的首要問題是必須要先閉合前面的單引號,這樣才能使後面的語句作為SQL執行,並且還要註釋掉原SQL語句中的後面的單引號,這樣才可以成功注入,由於代碼里使用了addslashes函數,黑客的攻擊會無從下手,但第二句沒有用引號包含變量,那黑客也不用考慮去閉合、註釋,所以即便同樣採用addslashes轉義,也還是存在SQL攻擊漏洞。