SQL注入原理及產生過程

最近在學習關於SQL注入方面的知識,想將一些相關的知識點作個彙總和筆記,方便往後的查閱也方便如今的學習。由於剛開始學習,涉獵尚未很深刻,本章將簡單的講講關於SQL注入的原理及其產生的過程和基本的一些加固方法。

1.理解SQL注入java

SQL注入是一種將SQL代碼插入或添加到應用(用戶)的輸入參數中的攻擊,以後再將這些參數傳遞給後臺的sql服務器加以解析和執行。因爲sql語句自己的多樣性,以及可用於構造sql語句的編程方法不少,所以凡是構造sql語句的步驟均存在被攻擊的潛在風險。Sql注入的方式主要是直接將代碼插入參數中,這些參數會被置入sql命令中加以執行。間接的攻擊方式是將惡意代碼插入字符串中,以後將這些字符串保存到數據庫的數據表中或將其當成元數據。當將存儲的字符串置入動態sql命令中時,惡意代碼就將被執行。

若是web應用未對動態構造的sql語句使用的參數進行正確性審查(即使使用了參數化技術),攻擊者就極可能會修改後臺sql語句的構造。若是攻擊者可以修改sql語句,那麼該語句將與應用的用戶具備相同的權限。當使用sql服務器執行與操做系統交互命令時,該進程將與執行命令的組件(如數據庫服務器、應用服務器或web服務器)擁有相同的權限,這種權限的級別一般很高。若是攻擊者執行以上惡意代碼的插入操做成功,那麼用戶數據庫服務器或者整個應用會遭到破壞,甚至被控制。
2.sql注入的產生過程及常見緣由
2.1產生過程
大多數的web應用都須要與數據庫進行交互,而且大多數web應用編程語言(如ASP、C##、.NET、Java和PHP)均提供了可編程的方法來與數據庫鏈接並進行交互。若是web應用開發人員沒法確保在將從web表單,cookie及輸入參數等收到的值傳遞給sql查詢(該查詢在數據庫服務器上執行)以前已經對其進行過驗證,那麼一般會出現sql注入漏洞,若是攻擊者可以控制發送給sql查詢的輸入,而且可以操縱該輸入將其解析爲代碼而非數據,那麼攻擊者就頗有可能有能力在後臺數據庫執行該代碼。web

2.2常見的sql注入產生緣由
基於此,SQL注入的產生緣由一般表如今如下幾方面:①轉義字符處理不合適;②不安全的數據庫配置;③不合理的查詢集處理;④不當的錯誤處理;⑤多個提交處理不當。正則表達式

2.2.1不當的處理類型
Sql數據庫將單引號字符(’)解析成代碼與數據間的分界線:單引號外面的內容軍事須要運行的代碼,而用單引號引發來的內容均是數據。由於只須要簡單的在URL或WEB頁面的字段中輸入一個單引號,就能很快速的識別出web站點是否會受到sql注入攻擊。sql

2.2.2不安全的數據庫配置數據庫

數據庫帶有不少默認的用戶預安裝內容。SQL Server使用聲名狼藉的「sa」做爲數據庫系統管理員帳戶,MySQL使用「root」和「anonymous」用戶帳戶,Oracle則在建立數據庫時一般會建立SYS、SYSTEM、DBSNMP和OUTLN帳戶。這些並不是是所有的帳號,知識比較出名的帳戶中的一部分,還有不少其餘的帳戶。其餘帳戶一樣按默認方式進行預設,口令總所周知。

這就帶來了很大的安全風險,攻擊者利用sql注入漏洞時,一般會常識訪問數據庫的元數據,好比內部的數據庫和表的名稱、列的數據類型和訪問權限,例如MySQL服務器的元數據位於information_schema虛擬數據庫中,可經過show databases;和show tables;命令訪問。全部的MySQL用戶均有權限訪問該數據庫中的表,但只能查看錶中那些與該用戶訪問權限相對應的對象的行。編程

2.2.3不合理的查詢集處理安全

有時須要使用動態的sql語句對某些複雜的應用進行編碼,由於程序開發階段可能還不知道要查詢的表或字段(或者不存在)。好比與大型數據庫交互的應用,這些數據庫在按期建立的表中的數據因爲應用已經產生了輸入,於是開發人員會信任該數據,攻擊者可使用本身的表和字段數據來替換應用產生的值,從而影響系統的返回值。

2.2.4不當的錯誤處理服務器

錯誤處理不當會爲web站點帶來不少安全方面的問題。最多見的問題是將詳細的內部錯誤消息(如錯誤代碼,數據庫轉存儲)顯示給用戶或攻擊。這些錯誤消息會泄露實現細節,爲攻擊者提供與網站潛在缺陷相關的重要線索。

2.2.5多個提交處理不當cookie

大型的web開發項目會出現這樣的問題:有些開發人員會對輸入進行驗證,而一些開發人員則不覺得然。對於開發人員,團隊,甚至公司來講,彼此獨立工做的情形並很多見,很難保證項目中每一個人都遵循相同的標準。
應用打開發人員還傾向於圍繞用戶來設計應用,他們儘量的使用預期的處理流程來引導用戶,認爲用戶將遵循他們已經設計好的邏輯順序。
例如:當用戶已到達一系列表單中的第三個表單時,他們會指望用戶確定已經完成第一個和第二個表達。但實際上,藉助URL亂序來請求資源,可以很是容易的避開預期的數據流程。
3.加固方法
最近學習的東西還不是很深刻,如下概括的一些關於針對sql注入的加固方法,是本人在學習中領悟和查閱資料總結的幾點,若是有一些不正確或者更好的建議,歡迎你們補充。

1.(簡單又有效的方法)PreparedStatement
採用預編譯語句集,它內置了處理SQL注入的能力,只要使用它的setXXX方法傳值便可。
使用好處:
(1).代碼的可讀性和可維護性.
(2).PreparedStatement盡最大可能提升性能.
(3).最重要的一點是極大地提升了安全性.
原理:
sql注入只對sql語句的準備(編譯)過程有破壞做用
而PreparedStatement已經準備好了,執行階段只是把輸入串做爲數據處理,
而再也不對sql語句進行解析,準備,所以也就避免了sql注入問題.jsp

2.使用正則表達式過濾傳入的參數
要引入的包:
import java.util.regex.*;
正則表達式:
private String CHECKSQL = 「^(.+)\sand\s(.+)|(.+)\sor(.+)\s$」;
判斷是否匹配:
Pattern.matches(CHECKSQL,targerStr);
下面是具體的正則表達式:
檢測SQL meta-characters的正則表達式 :
/(%27)|(’)|(--)|(%23)|(#)/ix
修正檢測SQL meta-characters的正則表達式 :/((%3D)|(=))1*((%27)|(’)|(--)|(%3B)|(:))/i
典型的SQL 注入攻擊的正則表達式 :/w*((%27)|(’))((%6F)|o|(%4F))((%72)|r|(%52))/ix
檢測SQL注入,UNION查詢關鍵字的正則表達式 :/((%27)|(’))union/ix(%27)|(’)
檢測MS SQL Server SQL注入攻擊的正則表達式:
/exec(s|+)+(s|x)pw+/ix
等等…..

3.字符串過濾
比較通用的一個方法:
(||之間的參數能夠根據本身程序的須要添加)
public static boolean sql_inj(String str)
{
String inj_str = "'|and|exec|insert|select|delete|update|
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
String inj_stra[] = split(inj_str,"|");
for (int i=0 ; i < inj_stra.length ; i++ )
{
if (str.indexOf(inj_stra[i])>=0)
{
return true;
}
}
return false;
}

4.jsp中調用該函數檢查是否包函非法字符

防止SQL從URL注入:
sql_inj.java代碼:

package sql_inj;
import java.net.*;
import java.io.*;
import java.sql.*;
import java.text.*;
import java.lang.String;
public class sql_inj{
public static boolean sql_inj(String str)
{
String inj_str = "'|and|exec|insert|select|delete|update|
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
//這裏的東西還能夠本身添加

>>>>閱讀全文

相關文章
相關標籤/搜索