如何從根本上防止SQL注入?
網(wǎng)友解答: 什么叫做 SQL注入?舉個例子:你后臺寫的 java 代碼拼的 sql 如下:// 該 ename 為前臺傳過來的一個查詢條件:而前臺頁面有個輸入框如下:職員姓名:_____
什么叫做 SQL注入?
舉個例子:你后臺寫的 java 代碼拼的 sql 如下:
// 該 ename 為前臺傳過來的一個查詢條件:
而前臺頁面有個輸入框如下:職員姓名:__________,該文本域?qū)?yīng)上面方法的 ename 參數(shù)。如果用戶在查詢時向職員姓名文本域中輸入的是如下信息:' or '1'='1,那么這時就會涉及到 sql 注入這個概念了。上面的字符串傳到后臺后,與其它 select 等字符串拼成了如下的語句:select empno,ename,deptno from emp where ename = '' or '1'='1'上面的 where 條件是永遠成立的, ,如果你的表中有權(quán)限限制,比如只能查詢本地市的信息,過濾條件中有地市過濾,不過因為輸入 ' or '1'='1 字符串后,條件永遠成立,導(dǎo)致你能看到所有城市的職員信息,那就會產(chǎn)生權(quán)限問題了,用戶能看到不該看到的信息。同理,如果是 insert 或者 update 等語句的話,通過 sql 注入會產(chǎn)生不可估量的問題。
這種不安全的情況是在 SQL 語句 在拼接的情況下發(fā)生。
解決方法:1.參數(shù)綁定。為了防范這樣”SQL 注入安全“可以用預(yù)編譯解決(不要用拼
接 SQL 字符串,可以用 prepareStatement,參數(shù)用 set 方法進行填裝 )。
2、檢查變量的數(shù)據(jù)類型和格式:
如果你的 SQL 語句是類似 where id={$id}這種形式, 數(shù)據(jù)庫里所有的 id 都是
數(shù)字,那么就應(yīng)該在 SQL 被執(zhí)行前,檢查確保變量 id 是 是 int 類型;如果是接受
郵箱,那就應(yīng)該檢查并嚴格確保變量一定是郵箱的格式,其他的類型比如日期、
時間等也是一個道理??偨Y(jié)起來: 只要是有固定格式的變量,在 SQL 語句執(zhí)行
前,應(yīng)該嚴格按照固定格式去檢查,確保變量是我們預(yù)想的格式, 這樣很大程
度上可以避免 SQL 注入攻擊。
比如,我們前面接受 username 參數(shù)例子中,我們的產(chǎn)品設(shè)計應(yīng)該是在用戶注冊的一開始, 就有一個用戶名的 命名 規(guī)則,比如 5-20 個字符,只能由大小寫字母、數(shù)字以及一些安全的符號組成,不包含特殊字符。此時我們應(yīng)該有一個check_username 的函數(shù)來進行統(tǒng)一的檢查。不過,仍然有很多例外情況并不能應(yīng)用到這一準則,比如文章發(fā)布系統(tǒng),評論系統(tǒng)等必須要允許用戶提交任意字符串的場景,這就需要采用過濾等其他方案了。( 使用正則表達式進行格式驗證!)3.所有的 SQL 語句都封裝在 存儲過程中。
所有的 SQL 語句都封裝在存儲過程中,這樣不但可以避免 SQL 注入,還能
提高一些性能。
網(wǎng)友解答:這是個好問題。
定義與解決思路sql injection的原因:用戶提交的參數(shù)可以入庫,并且當(dāng)做sql結(jié)構(gòu)化查詢語句執(zhí)行。
根本辦法: 杜絕用戶提交的參數(shù)入庫,并且阻止執(zhí)行。
SQL注入,一般發(fā)生在網(wǎng)站上。
如果網(wǎng)站程序是 JAVA語言可以用 prepareStatement, 作參數(shù)化綁定;
也可以用 存儲過程,SQL封裝在存儲過程中;
用ORM技術(shù),如 ibats, hibrnate 等;
如果網(wǎng)站程序是 .NET語言可以用 SqlParameter, 作參數(shù)化綁定;也可以用 存儲過程,SQL封裝在存儲過程中;
也可以用ORM技術(shù),如 EntityFrameWork, Dapper 等;
如果網(wǎng)站程序是其它程序,如 PHP語言不拼SQL,可能找不到其它的路;
但是 可以提煉一個公共函數(shù),自動過濾SQL關(guān)鍵詞(select, or, and,insert 等);
尤其要屏蔽那些攻擊性的關(guān)鍵詞如 update, delete, truncate, drop 等
拼接到字符串的傳參前后加個括號 與 反括號,可相對有效隔離危險。
希望能對大家有所幫助,謝謝。
(結(jié)束)