SQL隱碼攻擊問題

FreeeLinux發表於2017-03-30

sql注入

如果SQL當中,存在瀏覽器端請求的資料(使用者資料),使用者通過特殊的形式,對我們的sql語句產生影響,稱為sql注入(SQL Injection)。

$sql = "SELECT * FROM `p34_admin` WHERE admin_name='$admin_name' and admin_pass=md5('$admin_pass')";

例如上面的語句中,讓admin_name=’or 1 or’,那麼WHERE表示式恆成立。

tip:不僅在登入時,可以被注入,任何使用者資料參與執行,都可以被注入。

預防

  • 業務邏輯上預防(使用白名單,將使用者資料限制在合理範圍之內):
    • 通過限定資料格式(比如使用者名稱僅由字母、數字、下劃線和特定字元組成),如果檢測不安組要求,則直接不予參與SQL隱碼攻擊問題。
    • 通過限定數型別(比如,ID需要整形的資料,將使用者床底請求資料強制轉化成整型),進行避免。比如防止(DELETE FROM match where m_id=$_GET[‘m_id’]變為$GET[‘m_id’]=’5 or 1’#)。可以在後者前面加上(int)進行強制轉換。
  • 通過特殊資料轉義
    • 通過函式:PHP字串函式addslashes(),Mysql提供的轉義函式:mysql_real_escape_string(待轉義字串,連線)。

tip:PHP中魔術引號(magic quotes),PHP中自動為請求資料(GET,POST)增加轉義的一種防止SQL隱碼攻擊機制。

本文示例程式碼:
dao層:

class MySQLDB{
  /** 
    * avoid SQL Injection
    * @param $data string
    * @return string
    */
    public function escapeString($data) {
        return "'" . mysql_real_escape_string($data, $this->resourc) . "'";
    }   
}

model程式碼:

 class AdminModel{
   public function check($admin_name, $admin_pass) {
        //method1 
        //$admin_name = addslashes($admin_name);
        //$admin_psss = addslashes($admin_pass);

        //method2
        $admin_name_escape = $this->_dao->escapeString($admin_name);
        $admin_pass_escape = $this->_dao->escapeString($admin_pass);

        $sql = "SELECT * FROM `p34_admin` WHERE admin_name=$admin_name_escape 
               and admin_pass=md5($admin_pass_escape)";
        $row = $this->_dao->getRow($sql);
        return (bool)$row;  
    }   
}

相關文章