《電子技術應用》
您所在的位置:首頁 > 通信與網(wǎng)絡 > 設計應用 > 基于靜態(tài)分析的Java源代碼SQL注入檢測算法
基于靜態(tài)分析的Java源代碼SQL注入檢測算法
來源:電子技術應用2013年第4期
陳 豐, 余 蕓
南方電網(wǎng)公司信息部, 廣東 廣州510623
摘要: 研究了常見的SQL注入檢測和源代碼靜態(tài)分析掃描的原理,提出Java源代碼SQL注入檢測算法,該算法通過對Java源代碼詞法分析和語法分析、建立抽象語法樹、定義規(guī)則、遍歷語法樹和跟蹤等,檢測Java源代碼中可能的SQL注入路徑,測試結果表明,算法檢測效果良好,識別率高。
中圖分類號: TP309.5
文獻標識碼: A
文章編號: 0258-7998(2013)04-0137-04
A Java source-code SQL injection attack detection algorithm based on static analysis
Chen Feng, Yu Yun
China Sourthern Power Grid Co., Ltd, Guangzhou 510623, China
Abstract: This paper researches the method of SQL injection attack detection and the principle of static analysis scanning, and presents a Java source-code SQL injection attack detection algorithm. The detection algorithm includes these steps: lexical analysis of source code, parsing of source code, constructing abstract syntax tree of source code, defining rules, abstract syntax tree traversal, tracking problems, detecting possible paths of SQL injection attack etc. Test results show that the proposed detection algorithm performs perfectly and has higher recognition rate.
Key words : static analysis; SQL injection attack; abstract syntax tree

    SQL注入攻擊是一種常見的互聯(lián)網(wǎng)攻擊手段,它具有易操作、強隱蔽、高危害和難檢測等特點。由于SQL注入攻擊的對象是Web服務器后臺的數(shù)據(jù)庫,而數(shù)據(jù)庫往往存放重要的用戶數(shù)據(jù)或業(yè)務數(shù)據(jù),因而SQL注入攻擊的后果影響非常嚴重。特別對銀行、證券、電信、移動、政府以及電子商務企業(yè)等后臺數(shù)據(jù)庫。一旦遭受SQL注入而導致數(shù)據(jù)纂改或機密數(shù)據(jù)丟失,在經(jīng)濟角度和社會角度都將產(chǎn)生惡劣的影響。因此檢測和防范SQL注入是軟件安全領域的重要課題,具有極高的研究價值和意義。

    常見的Web應用系統(tǒng)架構如圖1所示,其中包括Web服務器及后臺數(shù)據(jù)庫。在Web服務器上部署Web服務,用戶使用瀏覽器通過Http或Https協(xié)議與Web服務器進行交互。常稱之為B/S架構。

    在該架構中,Web服務器向用戶提供各種應用服務,這些服務都涉及到與數(shù)據(jù)庫的交互,即伴執(zhí)行SQL語句。如果Web應用系統(tǒng)設計或實現(xiàn)不合理,將可能導致用戶對數(shù)據(jù)庫執(zhí)行的SQL語句偏離系統(tǒng)設計的預期,從而引發(fā)安全事故。
    Java程序運行在JVM中,因為具有與平臺無關的特點,這種完全面向對象開發(fā)的語言廣泛應用在Web系統(tǒng)的設計中。針對Java源代碼的SQL注入攻擊檢測進行研究,對于提高Web應用系統(tǒng)的安全性具有重要意義。
    本文介紹了SQL注入原理、目前的檢測方法以及Java代碼對數(shù)據(jù)庫操作的三種代碼結構。針對Java執(zhí)行SQL語句的特點,重點提出一種基于抽象語法樹進行SQL執(zhí)行路徑檢測的SQL注入檢測算法;在Web 應用程序發(fā)布前進行深入靜態(tài)分析和檢查,從而提高Web應用系統(tǒng)的安全性。算例分析和在實際Web系統(tǒng)中的應用結果表明,本文提出的SQL注入檢測算法具有高檢測率和低誤報率。
1 相關研究工作
    SQL注入漏洞最早在2000年左右被提出,其后學者們對SQL注入的檢測和防護展開了一系列的研究。
    典型的一種SQL注入例子如下:
    (1)用戶登錄Web應用系統(tǒng)時,需要進行身份認證,主要輸入用戶名和密碼兩個變量v_usr和v_pwd;
    (2)Web系統(tǒng)執(zhí)行合法性檢查的SQL語句為:“Select * from users where username=‘”+v_usr+“’and password=‘”+ v_pwd+“’”,如果用戶登錄時用戶取為‘admin’ or 1=1--,那么合法性檢查的SQL語句等效于Select * from users where username=‘ admin’ or 1=1;
    顯然,用戶名取‘admin’ or 1=1--時,無論密碼輸入多少,都可以登錄系統(tǒng)。
    SQL注入的檢測和防護方式目前主要有兩大類,一是系統(tǒng)上線前檢測,也稱為靜態(tài)檢測;二是系統(tǒng)在線運行防御,也稱為動態(tài)檢測。
    動態(tài)檢測方式是一種黑盒檢測方法,對上線的系統(tǒng)進行SQL漏洞掃描,編制SQL注入攻擊腳本對Web系統(tǒng)進行試探,通過檢查Http的回應報文內容來判斷是否發(fā)生SQL注入攻擊,從而確定是否存在SQL注入漏洞。AppScan等工具可執(zhí)行此類安全檢測。
    靜態(tài)檢測方法是一種白盒檢測方法[1],通過靜態(tài)語法解析查找Web 應用代碼中可能引發(fā)SQL注入的環(huán)節(jié),在Web應用發(fā)布前檢查代碼質量。Fotify等工具可執(zhí)行此類安全檢測。參考文獻[2-3]給出一種動態(tài)生成SQL語句進行類型正確性檢查的方法來檢測是否存在SQL注入,該方法的的缺點在于只能檢測句法結構或語句類型出現(xiàn)異常的SQL注入問題。參考文獻[4]提出一種自動推理機的方法對添加了輸入值后的SQL語句進行檢查,該方法的缺點在于只能檢測出重言式的SQL注入攻擊。此外,還有一些學者采用機器學習算法對SQL注入漏洞進行檢測[5],這一類檢測方法的檢測率和誤報率往往依賴于訓練集的大小。
2 Java源代碼靜態(tài)掃描分析思路
    程序靜態(tài)分析指在不執(zhí)行程序的情況下,通過自動掃描代碼發(fā)現(xiàn)隱含的程序隱患[6],具備執(zhí)行速度快、效率高等優(yōu)點。對源代碼進行靜態(tài)分析時借鑒編譯技術的詞法分析和語法分析。源代碼進行靜態(tài)分析掃描原理如圖2所示。

    Java程序與數(shù)據(jù)庫之間的交互主要通過Java數(shù)據(jù)庫連接JDBC進行。其數(shù)據(jù)庫操作涉及與數(shù)據(jù)庫建立連接、發(fā)送SQL指令、處理返回結果、斷開數(shù)據(jù)庫連接4個步驟。
    具體實現(xiàn)上主要涉及的Java類有Connection類、DriverManager類、Statement類、ResultSet類、PreparedStatement類和callableStatement類。在代碼實現(xiàn)上往往有3種實現(xiàn)方式:
    (1) 常規(guī)方式
                                           //函數(shù) DB_SQL(SQL語句)
     Connection con=DriverManager. getConnection(參數(shù)URL,參數(shù)用戶名,參數(shù)密碼);
     Statement stat = con.createStatement();
     ResultSet rs = stat.executeQuery("SQL語句");(或者executeUpdate /execute /executeBatch)
                                             //此處為rs的處理代碼
    rs.close(); stat.close(); con.close();
    Java采用常規(guī)方式訪問數(shù)據(jù)庫,每次都需要進行建立連接,再執(zhí)行SQL語句,最后釋放連接。由于建立連接過程一般比較耗時(一般需要幾十毫秒至幾百毫秒之間),而且Statement對象每次執(zhí)行SQL語句的解析和編譯也比較耗時,如果涉及如下循環(huán)使用情況,則代碼的執(zhí)行效率將會比較低下。為此,對于需要頻繁建立數(shù)據(jù)庫連接的情況,可以采用連接池方式進行優(yōu)化;對于需要頻繁執(zhí)行相似SQL語句的情況,則可采用預編譯方式進行優(yōu)化。
    while(N次)
     {
      DB_SQL(SQL語句);
  }    
    (2) 預編譯方式
    采用常規(guī)方式執(zhí)行SQL語句時,DBMS需要對SQL語句進行解析和編譯;而采用預編譯方式時,DBMS只在第一次對SQL語句進行解析和編譯。相比前者,后者更難注入SQL。原因在于,PreparedStatement對象執(zhí)行SQL語句前,需要設置“?”號對應的變量,例如ps.setInt(1,變量v1)、ps.setLong(2,變量v2) 表示SQL語句中第一個“?”號是int型、值為“變量v1”;這樣在安全性上相當于增加了一個類型匹配。
     Connection con=DriverManager.getConnection(參數(shù)URL,參數(shù)用戶名,參數(shù)密碼);
     while(N次)
     {
      PreparedStatement ps = con.prepareStatement(帶若干“?”號的SQL語句);
     ps.setXX(“?”的序號, 變量);   //XX包括int double等
    ResultSet rs = ps.executeQuery();(或者executeUpdate /execute /executeBatch)
                                  //此處為rs的處理代碼
      rs.close();
      }
     ps.close(); con.close();
    (3) 連接池方式
    連接池(Connection Pool)是設計模式中資源池(Resource Pool)的一種具體應用,主要解決資源頻繁分配和釋放所帶來的性能問題。其基本思想是預先建立一個數(shù)據(jù)庫連接池,在該連接池中預先存放一定數(shù)量的連接,當需要建立數(shù)據(jù)庫連接時,并非新建一個數(shù)據(jù)庫連接,而是從連接池中取出一個連接對象,然后對該連接對象進行參數(shù)設置和使用,使用完畢后,并不釋放該連接,而是將連接對象的參數(shù)復位并回收。
    采用連接池的應用開發(fā)方式與常規(guī)方式的代碼結構類似。區(qū)別是常規(guī)方式的連接對象在需要時才從堆中動態(tài)分配空間與數(shù)據(jù)庫建立連接,使用完畢后即斷開連接,等待Java的GC垃圾回收器發(fā)現(xiàn)該對象不再需要后,將回收連接對象的內存空間;而采用連接池方式,則是在連接池中預先建立一個若干數(shù)據(jù)的連接對象,需要使用時才從連接池中取出一個連接對象(不是臨時創(chuàng)建,因此效率高),使用完畢后,并不斷開連接,而是將該連接對象歸還給對象池。通過一個“借用”和“歸還”的方式使得可以高效地對付頻繁的數(shù)據(jù)庫訪問操作。目前常用的連接池主要有C3PO、BoneCP、DBCP、Proxool等。
    綜上所述,無論采用哪一種數(shù)據(jù)庫操作方式,Java源代碼中可能出現(xiàn)SQL注入漏洞的代碼執(zhí)行過程中,一定經(jīng)過executeQuery、executeUpdate、execute 或executeBatch函數(shù)。本文提出的SQL檢測算法,正是通過定位這些函數(shù)并以此為分析SQL注入隱患的切入點,跟蹤這些函數(shù)的參數(shù)或參數(shù)表達式。如果這些參數(shù)表達式最終能追溯到某個特定的對象(如HttpServletRequest),則可以肯定這條路徑將可能存在SQL注入隱患。
3 Java源代碼SQL注入檢測算法
    抽象語法樹AST(Abstract Syntax Tree)是程序源代碼的抽象語法結構的樹狀表現(xiàn)形式,樹上的每個節(jié)點表示源代碼中的一種結構,AST的好處在于不依賴于具體的方法和語言細節(jié)。對于源代碼的文法分析,首先進行詞法分析,將源代碼中所有字符串從前至后逐個字符進行掃描,并對每個“單詞”進行標識。這些“單詞”主要包括Java語言中的關鍵字、標識符、運算符和分隔符等。然后進行語法分析,將這些識別出來的“單詞”序列分解成各類Java語法單位。
    根據(jù)源代碼靜態(tài)分析掃描原理,結合Java 1.6的文法定義,本文提出的SQL注入檢測算法通過對源代碼的詞法和語法分析,生成相應的抽象語法樹,定義規(guī)則,根據(jù)規(guī)則遍歷抽象語法樹。
    本文提出的檢測算法實現(xiàn)步驟如下:
    (1) 遍歷抽象語法樹,尋找METHOD_DECL結點中節(jié)點名為executeQuery或executeUpdate或execute或executeBatch的所有節(jié)點,并將它們保存在哈希表keyNode中。
    (2) 找keyNode中的每一個節(jié)點,確認是否是正確的結點。首先得到keyNode節(jié)點的前繼表達式,并得到前繼表達式的返回值類型。若前繼表達式的返回值類型為Java.sql.Statement,則可確認此結點,并轉到下一步;若返回值類型不是Java.sql.Statement,則轉步驟(2),檢測下一個節(jié)點;
    (3) 確認結點,取得第一個參數(shù)作為路徑結點,分析并跟蹤路徑結點的數(shù)據(jù)流。具體為:分析并跟蹤路徑結點表達式為變量表達式;分析并跟蹤路徑結點表達式為方法表達式;跟蹤退出的準則描述如下:①當所有跟蹤變量均到達常量定值,則此路徑不會產(chǎn)生SQL注入漏洞,轉步驟(2);②跟蹤到開始API定義的方法結點,轉步驟(4)。
    (4) 記錄跟蹤到的SQL注入的侵入路徑,轉步驟(2),檢測下一個節(jié)點。若keyNode中所有結點都已檢測完成,則算法終止。
4 算法實驗
  為了驗證本文提出的算法的有效性,以一個Java程序為實驗算例進行分析和說明,實驗算例代碼如圖3所示。
    在實驗的Java源代碼中,可能產(chǎn)生SQL注入的開始API和結束API(即Java源代碼SQL注入檢測規(guī)則),具體如表1所示。

    根據(jù)SQL注入檢測規(guī)則,利用本文所提出的檢測算法對圖3所示的Java源代碼進行掃描分析,產(chǎn)生的抽象語法樹如圖4所示,可發(fā)現(xiàn)SQL注入漏洞,并報告相應的路徑。

    本文提出的SQL注入檢測算法已經(jīng)成功應用于本單位信息系統(tǒng)的Java源代碼靜態(tài)檢測中。在新上線運行的某Web系統(tǒng)(約10萬行代碼)靜態(tài)分析中,檢測時間僅為5 s,檢測準確識別率高達90%,而誤報率僅有10%;通過實驗和實際系統(tǒng)的測試和驗證,本文提出的Java源代碼SQL注入靜態(tài)分析算法具有很好的應用效果和前景。
參考文獻
[1] WILLIAM G J, VIEGAS H J, ORSO A. A classification of SQL injection attacks and countermeasures[C]. Proc. of International Symposium on Secure Software Engineering.2006.
[2] GOULD C, SU Z, DEVANBU P. JDBC checker: a static analysis tool for SQL/JDBC applications[C]. Proceeding of  the 26th International conference on Software Engineering(ICSE). Washington D C: IEEE computer Society, 2004.
[3] GOULD C, SU Z, DEVANBU P. Static checking of dynamically generated queries in database applications[C].Proceedings of 26th International Conference on Software Engineering, 2004.
[4] WASSERMANN G, SU Z. An analysis framework for security in Web applications[C]. Proceedings of the FSE Work  shop on Specification and Verification of Component  Based System, 2004.
[5] HUANG Y W, HUANG S K, LIN T P, et al. Web application security assessment by fault injection and behavior  monitoring[C]. Porceeding of the 11th International World Wide Conferecne, 2002.
[6] 張卓.SQL注入攻擊技術及防范措施研究[D].上海:上海交通大學,2007.

此內容為AET網(wǎng)站原創(chuàng),未經(jīng)授權禁止轉載。