程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> 其他數據庫知識 >> MSSQL >> 進攻SQL注入的辦法總結

進攻SQL注入的辦法總結

編輯:MSSQL

進攻SQL注入的辦法總結。本站提示廣大學習愛好者:(進攻SQL注入的辦法總結)文章只能為提供參考,不一定能成為您想要的結果。以下是進攻SQL注入的辦法總結正文


SQL 注入是一類傷害極年夜的進擊情勢。固然傷害很年夜,然則進攻卻遠遠沒有XSS那末艱苦。

SQL 注入可以拜見:https://en.wikipedia.org/wiki/SQL_injection

SQL 注入破綻存在的緣由,就是拼接 SQL 參數。也就是將用於輸出的查詢參數,直接拼接在 SQL 語句中,招致了SQL 注入破綻。

1. 演示下經典的SQL注入

我們看到:select id,no from user where id=2;

假如該語句是經由過程sql字符串拼接獲得的,好比: String sql = "select id,no from user where id=" + id;

個中的 id 是一個用戶輸出的參數,那末,假如用戶輸出的是 2, 那末下面看到查到了一條數據,假如用戶輸出的是 2 or 1=1 停止sql注入進擊,

那末看到,下面的語句(select id,no from user where id=2 or 1=1;)將user表中的一切記載都查出來了。

這就是典范的sql注入。

再看一列:

我們看到經由過程 sql 注入可以或許直接將表 sqlinject 刪除失落!可見其傷害!

2. sql 注入的緣由

sql注入的緣由,外面上說是由於 拼接字符串,組成sql語句,沒有應用 sql語句預編譯,綁定變量。

然則更深條理的緣由是,將用戶輸出的字符串,當做了 “sql語句” 來履行。

好比下面的 String sql = "select id,no from user where id=" + id;

我們願望用戶輸出的 id 的值,僅僅作為一個字符串字面值,傳入數據庫履行,然則當輸出了: 2 or 1=1 時,個中的 or 1=1 並沒有作為 where id= 的字面值,而是作為了 sql語句 來履行的。所以其實質是將用戶的輸出的數據,作為了敕令來履行。

3. sql注入的進攻

1> 根本上年夜家都曉得 采取sql語句預編譯和綁定變量,是進攻sql注入的最好辦法。然則個中的深條理緣由就不見得都懂得了。

 String sql = "select id, no from user where id=?";
    PreparedStatement ps = conn.prepareStatement(sql);
    ps.setInt(1, id);
    ps.executeQuery();

如上所示,就是典范的采取 sql語句預編譯和綁定變量 。為何如許便可以避免sql 注入呢?

其緣由就是:采取了PreparedStatement,就會將sql語句:"select id, no from user where id=?" 事後編譯好,也就是SQL引擎會事後停止語法剖析,發生語法樹,生成履行籌劃,也就是說,前面你輸出的參數,不管你輸出的是甚麼,都不會影響該sql語句的語法構造了,由於語法剖析曾經完成了,而語法剖析重要是剖析sql敕令,好比 select ,from ,where ,and, or ,order by 等等。所以即便你前面輸出了這些sql敕令,也不會被當做sql敕令來履行了,由於這些sql敕令的履行, 必需先的經由過程語法剖析,生成履行籌劃,既然語法剖析曾經完成,曾經預編譯過了,那末前面輸出的參數,是相對弗成能作為sql敕令來履行的,只會被當作字符串字面值參數。所以sql語句預編譯可以進攻sql注入。

2> 然則不是一切場景都可以或許采取 sql語句預編譯,有一些場景必需的采取 字符串拼接的方法,此時,我們嚴厲檢討參數的數據類型,還有可使用一些平安函數,來方法sql注入。

好比 String sql = "select id,no from user where id=" + id;

在吸收到用戶輸出的參數時,我們就嚴厲檢討 id,只能是int型。龐雜情形可使用正則表達式來斷定。如許也是可以避免sql注入的。

平安函數的應用,好比:  

 MySQLCodec codec = new MySQLCodec(Mode.STANDARD);
    name = ESAPI.encoder().encodeForSQL(codec, name);
    String sql = "select id,no from user where name=" + name;

ESAPI.encoder().encodeForSQL(codec, name)
該函數會將 name 中包括的一些特別字符停止編碼,如許 sql 引擎就不會將name中的字符串當做sql敕令來停止語法剖析了。

注:

現實項目中,普通我們都是采取各類的框架,好比ibatis, hibernate,mybatis等等。他們普通也默許就是sql預編譯的。關於ibatis/mybatis,假如應用的是 #{name}情勢的,那末就是sql預編譯,應用 ${name} 就不是sql預編譯的。

以上就是SQL注入進攻辦法總結,願望對年夜家以後的進修有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved