溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Java最新的SQL注入原因以及預(yù)防方案

發(fā)布時(shí)間:2021-08-31 12:37:40 來(lái)源:億速云 閱讀:136 作者:chen 欄目:編程語(yǔ)言

這篇文章主要講解了“Java最新的SQL注入原因以及預(yù)防方案”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Java最新的SQL注入原因以及預(yù)防方案”吧!

 前沿

在現(xiàn)有的框架中sql防注入已經(jīng)做得很好了,我們需要做的就是盡量不要使用sql拼接調(diào)用

java sql注入原因以及預(yù)防方案(易理解)

1. SQL注入

1.1 原理

SQL注入是通過(guò)客戶(hù)端的輸入把SQL命令注入到一個(gè)應(yīng)用的數(shù)據(jù)庫(kù)中,從而執(zhí)行惡意的SQL語(yǔ)句。

1.2 演示

1.2.1 案例1

有一個(gè)登錄框,需要 輸入用戶(hù)名和密碼 ,然后我們的密碼輸入 'or '123' = '123  這樣的。我們?cè)诓樵?xún)用戶(hù)名和密碼是否正確的時(shí)候,本來(lái)執(zhí)行的sql語(yǔ)句是:select * from user where username = '' and  password = ''. 這樣的sql語(yǔ)句,現(xiàn)在我們輸入密碼是如上這樣的,然后我們會(huì)通過(guò)參數(shù)進(jìn)行拼接,拼接后的sql語(yǔ)句就是:

select * from user where username = '' and password = ' ' or '123' = '123  ';這樣的了,那么會(huì)有一個(gè)or語(yǔ)句,只要這兩個(gè)有一個(gè)是正確的話,就條件成立,因此 123 = 123  是成立的。因此驗(yàn)證就會(huì)被跳過(guò)。這只是一個(gè)簡(jiǎn)單的例子,

1.2.2 案例2

密碼比如是這樣的:'; drop table user;, 這樣的話,那么sql命令就變成了:

select * from user where username = '' and password = ''; drop table user;',  那么這個(gè)時(shí)候我們會(huì)把user表直接刪除了。

1.3 防范

1.3.1 前端

前端表單進(jìn)行參數(shù)格式控制;

1.3.2 后端

  • 我們可以使用預(yù)編譯語(yǔ)句(PreparedStatement,這  樣的話即使我們使用sql語(yǔ)句偽造成參數(shù),到了服務(wù)端的時(shí)候,這個(gè)偽造sql語(yǔ)句的參數(shù)也只是簡(jiǎn)單的字符,并不能起到攻擊的作用。

  • 使用正則表達(dá)式過(guò)濾傳入的參數(shù)

注意: 永遠(yuǎn)也不要把未經(jīng)檢查的用戶(hù)輸入的值直接傳給數(shù)據(jù)庫(kù)

  • java中的驗(yàn)證字符串是否包含sql的判斷

package cn.javanode.thread;  import java.util.regex.Pattern;  /**  * @author xgt(小光頭)  * @version 1.0  * @date 2021-1-8 11:48  */ public class CheckSqlDemo {      /**正則表達(dá)式**/     private static String reg = "(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|"             + "(\\b(select|update|union|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)";       private static Pattern sqlPattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);      private static boolean isValid(String str) {         if (sqlPattern.matcher(str).find())         {             System.out.println("未能通過(guò)過(guò)濾器:str=" + str);             return false;         }         return true;     }      public static void main(String[] args) {         System.out.println(isValid("tongji_user_add"));     }  }

補(bǔ)充

PreparedStatement是如何防止SQL注入的?

1. 拼接參數(shù)(sql注入)

Connection connection = DriverManager.getConnection(DB_URL, USER, PASS);         PreparedStatement preparedStatement = connection.prepareStatement(sql);                 String param = "'test' or 1=1";         String sql = "select file from file where name = " + param; // 拼接SQL參數(shù)         ResultSet resultSet = preparedStatement.executeQuery();         System.out.println(resultSet.next());

輸出結(jié)果為 true ,DB中執(zhí)行的SQL為

-- 永真條件1=1成為了查詢(xún)條件的一部分,可以返回所有數(shù)據(jù),造成了SQL注入問(wèn)題 select file from file where name = 'test' or 1=1

2. setString (防注入)

Connection connection = DriverManager.getConnection(DB_URL, USER, PASS);         PreparedStatement preparedStatement = connection.prepareStatement(sql);             preparedStatement.setString(1,account);//設(shè)置參數(shù)         preparedStatement.setString(2,password);         ResultSet resultSet = preparedStatement.executeQuery();//執(zhí)行查詢(xún)sql,獲取結(jié)果集

輸出結(jié)果為 false ,DB中執(zhí)行的SQL為

select file from file where name = '\'test\' or 1=1'

我們可以看到輸出的 SQL是把整個(gè)參數(shù)用引號(hào)包起來(lái),并把參數(shù)中的引號(hào)作為轉(zhuǎn)義字符,從而避免了參數(shù)也作為條件的一部分

3. 源碼分析

結(jié)論

  • preparedStatement.setString 會(huì)判斷當(dāng)前參數(shù)的符號(hào)是否需要轉(zhuǎn)義,是的話加的轉(zhuǎn)義符

  • 如果不需要,則直接加上引號(hào)

Java最新的SQL注入原因以及預(yù)防方案

//完整代碼 public void setString(int parameterIndex, String x) throws SQLException {        synchronized (checkClosed().getConnectionMutex()) {            // if the passed string is null, then set this column to null            if (x == null) {                setNull(parameterIndex, Types.CHAR);            } else {                checkClosed();                 int stringLength = x.length();                 if (this.connection.isNoBackslashEscapesSet()) {                    // Scan for any nasty chars                    // 判斷是否需要轉(zhuǎn)義                    boolean needsHexEscape = isEscapeNeededForString(x, stringLength);                     if (!needsHexEscape) {                        byte[] parameterAsBytes = null;                         StringBuilder quotedString = new StringBuilder(x.length() + 2);                        quotedString.append('\'');                        quotedString.append(x);                        quotedString.append('\'');                         if (!this.isLoadDataQuery) {                            parameterAsBytes = StringUtils.getBytes(quotedString.toString(), this.charConverter, this.charEncoding,                                    this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), getExceptionInterceptor());                        } else {                            // Send with platform character encoding                            parameterAsBytes = StringUtils.getBytes(quotedString.toString());                        }                         setInternal(parameterIndex, parameterAsBytes);                    } else {                        byte[] parameterAsBytes = null;                         if (!this.isLoadDataQuery) {                            parameterAsBytes = StringUtils.getBytes(x, this.charConverter, this.charEncoding, this.connection.getServerCharset(),                                    this.connection.parserKnowsUnicode(), getExceptionInterceptor());                        } else {                            // Send with platform character encoding                            parameterAsBytes = StringUtils.getBytes(x);                        }                         setBytes(parameterIndex, parameterAsBytes);                    }                     return;                }

感謝各位的閱讀,以上就是“Java最新的SQL注入原因以及預(yù)防方案”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Java最新的SQL注入原因以及預(yù)防方案這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI