php web開發安全之sql注入和防范:(一)簡單的select語句注入和防范


sql注入主要是指通過在get、post請求參數中構造sql語句,以修改程序運行時所執行的sql語句,從而實現獲取、修改信息甚至是刪除數據的目的,sql被注入的原因主要是代碼編寫的有問題(有漏洞),只要平時注意在編寫與sql相關的代碼時養成良好的習慣,對可能被注入的sql語句加以防范,那么在大部分情況下是可以防范sql注入的。下面看下哪些不好的編碼習慣容易引起select語句被注入,並分析下防范措施。

注意:這里沒有完整的php代碼,可以大致假設一個場景:用戶可以通過類似下面的url地址http://localhost/user.php?username=yang或http://localhost/user.php?uid=yang,通過get方法來請求數據庫中的信息,數據庫中有user、article表。

1,sql語句中的替換變量不加引號
看下這條語句 $sql = "select uid, username from user where uid = $uid "; 
替換變量不加引號,如果用戶輸入這樣的$uid:$uid = '1 and 1=2 union select * from article where aid = 1';

那么可以構造出這樣的sql

select uid, username from user where uid = 1 and 1=2 union select * from article where aid = 1

可以看到結合union,就可以對其他表中的數據進行查詢。

所以,sql語句中的變量應該要加上引號 $sql = "select uid, username from user where uid = '$uid'"; 
這樣即便被sql注入,被構造的sql語句也只會變成這樣:

select uid, username from user where uid = '1 and 1=2 union select * from article where aid = 1';

這樣構造出的uid就只能是sql語句中查詢參數的值,也就起不到注入作用了。

2,未對用戶的輸入進行過濾和轉義

(1)過濾,對數據進行過濾,將其轉換為自己需要的格式,或者判斷數據格式是否合法。判斷數據格式是否合法這個要按照自己定義的規則來進行,比如email地址格式、用戶名長度和組合、密碼長度和組合等,這里先不討論數據格式合法性的問題。下面先簡單看下格式轉換問題:

對於按id查找的sql,因為id一般為整數,所以可以先將用戶輸入的數據類型轉換為int,這樣即使用戶嘗試構造$uid為:

 $uid = (int)'1 and 1=2 union select * from article where aid = 1' ,

它也會被轉換為數字,這在一定程度上能夠避免被注入。

(2)對於按如username字符串類型查找的sql,面臨的主要注入風險是通過在參數中加上單引號、sql注釋符、sql語句結束符等符號來構造sql,所以只要注意將這些字符進行轉義即可,也就是對用戶輸入的數據進行轉義,這里涉及到兩個函數:addslashes()和 addcslashes()。addslashes()可以對單引號'、雙引號"、反斜線\和NUL(NULL字符)進行轉義。addcslashes()可以自定義需要轉義的字符,下面來看下利用addcslashes()對用戶的輸入進行轉義。

比如下面這條sql語句:

$sql = "select uid, username from user where username = '{$username}' ";

在不進行轉義的時候,用戶可以構造$username如下: yang';SHOW TABLES-- inject 
最后構造出如下的sql:

select uid, username from user where username = 'yang';SHOW TABLES-- inject';

現在我們用addcslashes()函數對$username進行轉義,

$username = isset($_GET['username']) ? addcslashes($_GET['username'], "'\"%_\\;-") : '';

注意上面的語句會對下面的字符進行轉義 ,可以根據實際需要轉義相應的字符。

' 單引號
" 雙引號
% 百分號
_ 下划線
\ 反斜線
; 分號
- 小破折號

這時如果用戶構造的 yang';SHOW TABLES-- inject 就會變成這個樣子: yang\'\;SHOW TABLES\-\- inject ,構造的sql會變成這樣:

select uid, username from user where username = 'yang\'\;SHOW TABLES\-\- inject';

可以說是慘不忍睹了,sql注入也就失效了。

3,小結

上面只是簡單的分析了容易被sql注入的兩個不好的編程習慣和相應的防范,其實sql注入的方式、方法還有很多,所謂魔高一尺、道高一丈,需要學習的地方還有很多。

 參考:

php程序設計

Web安全之SQL注入攻擊技巧與防范


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM