首先,SQL陳述句應該考慮哪些安全性?
第一,防止SQL注入,對特殊字符進行過濾、轉義或者使用預編譯的SQL陳述句系結變數,
第二,當SQL陳述句運行出錯時,不要把資料庫回傳的錯誤資訊全部顯示給用戶,以防止泄露服務器和資料庫相關資訊,
其次,什么叫做SQL注入呢,如何防止呢?
舉個例子:
你后臺寫的Java代碼拼的SQL如下:
1 //該ename為前臺傳過來的一個查詢條件
2 public List getInfo(String ename){
3 StringBuffer buf = new StringBuffer();
4 buf.append("select empno,ename,deptno from emp where ename = "").append(ename).append("");
5 ...
6 ...
7 }
而前臺頁面有輸入框如下:
職員姓名:
該文本域對應上面方法的ename引數,
如果用戶在查詢時向職員姓名文本域中輸入的是如下資訊:
'or'1'='1
那么這時就會涉及到SQL注入這個概念了,
上面的字串傳到后臺后,與其他select等字串拼成了如下的陳述句:
select empno,ename,deptno from emp where ename=" or '1'='1'
上面的where條件是永遠成立的,如果你的表中有權限限制,比如只能查詢本地市的資訊,過濾條件中有地市過濾,不過因為輸入'or'1'='1字串后,條件永遠成立,導致你能看到所有城市的職員資訊,那就會產生權限問題了,用戶能看到不該看到的資訊,同理,如果是insert或者update等陳述句的話,通過SQL諸如會產生不可估量的問題,
這種不安全的情況是在SQL陳述句在拼接的情況下發生,
解決方法:
1、引數系結,為了防范這樣“SQL注入安全”可以用預編譯(不要用拼接SQL字串,可以用prepareStatement,引數用set方法進行填裝),
1 String sql="insert into userlogin values(?,?)";
2 try{
3 PrepareStatement ps = conn.prepareStatement(sql);
4 for(int i=1;i<100;i++){
5 ps.setInt(1,i);
6 ps.setInt(2,8888);
7 ps.executeUpdate();
8 }
9 ps.close();
10 conn.close();
11 }catch(SQLException e){
12 e.printStackTrace();
13 }
2、檢查變數的資料型別和格式
如果你的SQL陳述句市類似where id={$id}這種形式,資料庫里所有的id都是數字,那么就應該在SQL被執行前,檢查確保變數id是int型別;如果是接受郵箱,那就應該檢查并嚴格確保變數一定是郵箱的格式,其他的型別比如日期、時間等也是一個道理,總結起來:只要是有固定格式的變數,在SQL陳述句執行前,應該嚴格固定格式去檢查,確保變數是我們預想的格式,這樣很大程度上可以避免SQL注入攻擊,
比如,我們前面接受username引數例子中,我們的產品設計應該是在用戶注冊的一開始,就有一個用戶名的命名規則,比如5-20個字符,只能由大小寫字母、資料以及一些安全的符號組成,不包含特殊字符,此時我們應該有一個check_username的函式來進行統一的檢查,不過,仍然有很多例外情況并不能應用到這一準則,比如文章發布系統,評論系統等必須要允許客戶提交任意字串的場景,這就需要采用過濾等其他方案了,(使用正則運算式進行格式驗證!)
3、所有的SQL陳述句都封裝在存盤程序中
所有的SQL陳述句都封裝在存盤程序中,這樣不但可以避免SQL注入,還能提高一些性能,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/66604.html
標籤:MySQL
上一篇:MySQL事務隔離級別與相關示例(臟讀、不可重復讀、幻讀)
下一篇:mysql刷題(不定時更新)
