中安威士:詳解SpringMVC框架中常見漏洞的防御-創(chuàng)新互聯(lián)

下面我們就用利用SpringMVC自帶的數(shù)據(jù)庫(kù)操作類jdbcTemplate舉例。比如下面Dao中有如下的兩個(gè)函數(shù)。

創(chuàng)新互聯(lián)公司主要從事成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)乾安,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):18980820575

函數(shù)save使用的是綁定變量的形式很好的防止了sql注入,而queryForInt_函數(shù)接收id參數(shù)直接對(duì)sql語(yǔ)句進(jìn)行了拼接,測(cè)試時(shí)出現(xiàn)sql注入。

public static void save(String username,String password) {    

        jdbcTemplate.update("insert into test_table(user_name,password) values(?,?)",     

                new Object[]{username,password});    

    }  

  

public static int queryForInt_(String id){    

            return jdbcTemplate.queryForInt("select count(0) from test_table where id = " + id);    

        }

#為了方便僅僅貼出了DAO層代碼

所以,在java代碼的開發(fā)過(guò)程中,我們盡量避免使用拼接sql語(yǔ)句的形式去執(zhí)行數(shù)據(jù)庫(kù)語(yǔ)句。如果需要使用拼接sql語(yǔ)句的形式進(jìn)行數(shù)據(jù)庫(kù)查詢,那么OWASP提供了一個(gè)防御sql注入的Esapi包,這個(gè)包中的encodeForSQL方法能對(duì)sql注入進(jìn)行很好的防御。

接著我們就分析下這個(gè)encodeForSQL方法。

首先我們介紹這個(gè)方法的使用,使用時(shí)調(diào)用如下,不同的數(shù)據(jù)庫(kù)使用不到的方法。

//防止Oracle注入  

ESAPI.encoder().encodeForSQL(new OracleCodec(),queryparam)  

//防止mysql注入  

ESAPI.encoder().encodeForSQL(new MySQLCodec(Mode.STANDARD),queryparam) //Mode.STANDARK為標(biāo)準(zhǔn)的防注入方式,mysql一般用使用的是這個(gè)方式  

//防止DB2注入  

ESAPI.encoder().encodeForSQL(new DB2Codec(),queryparam)  

  

  

//防止Oracle注入的方法例子,為了方便僅僅給出sql語(yǔ)句的拼接部分  

Codec ORACLE_CODEC = new OracleCodec();  

String query ="SELECT user_id FROM user_data WHERE user_name = ‘"+ESAPI.encoder().encodeForSQL(ORACLE_CODEC,req.getParameter("userID"))+"’ and user_password = ‘"+ESAPI.encoder().encodeForSQL(ORACLE_CODEC,req.getParameter("pwd"))+"’";

下面我們就用mysql為例字分析encodeForSQL函數(shù)做了什么防御。具體函數(shù)過(guò)

程就不跟蹤了,直接分析最后調(diào)用了哪個(gè)方法。根據(jù)代碼可知最后調(diào)用的是encodeCharacter方法。

public String encodeCharacter( char[] immune, Character c ) {  

        char ch = c.charValue();  

          

        // check for immune characters  

        if ( containsCharacter( ch, immune ) ) {  

            return ""+ch;  

        }  

          

        // check for alphanumeric characters  

        String hex = Codec.getHexForNonAlphanumeric( ch );  

        if ( hex == null ) {  

            return ""+ch;  

        }  

          

        switch( mode ) {  

            case ANSI: return encodeCharacterANSI( c );  

            case STANDARD: return encodeCharacterMySQL( c );  

        }  

        return null;  

    }

上述方法中containsCharacter函數(shù)是不進(jìn)行驗(yàn)證的字符串白名單,Codec.getHexForNonAlphanumeric函數(shù)查找字符傳中是否有16進(jìn)制,沒有返回空值。

而encodeCharacterANSI和encodeCharacterMySQL才是防御的重點(diǎn),我們看一下這兩個(gè)函數(shù)的不同,如果選擇的我們選擇是Mode.ANSi模式,則字符串則進(jìn)入下面的函數(shù),可以看到這個(gè)函數(shù)對(duì)單撇號(hào)和雙撇號(hào)進(jìn)行了轉(zhuǎn)義。

private String encodeCharacterANSI( Character c ) {  

    if ( c == '\'' )  

        return "\'\'";  

    if ( c == '\"' )  

        return "";  

    return ""+c;  

}

如果選擇的是Mode.STANDARD模式,則字符串 則進(jìn)入下面的函數(shù),可以看到這個(gè)函數(shù)對(duì)單撇號(hào)和雙撇號(hào)、百分號(hào)、反斜線等更多的符號(hào)進(jìn)行了轉(zhuǎn)換,所以使用時(shí)推薦使用標(biāo)準(zhǔn)模式。

private String encodeCharacterMySQL( Character c ) {  

    char ch = c.charValue();  

    if ( ch == 0x00 ) return "\\0";  

    if ( ch == 0x08 ) return "\\b";  

    if ( ch == 0x09 ) return "\\t";  

    if ( ch == 0x0a ) return "\\n";  

    if ( ch == 0x0d ) return "\\r";  

    if ( ch == 0x1a ) return "\\Z";  

    if ( ch == 0x22 ) return "\\\"";  

    if ( ch == 0x25 ) return "\\%";  

    if ( ch == 0x27 ) return "\\'";  

    if ( ch == 0x5c ) return "\\\\";  

    if ( ch == 0x5f ) return "\\_";  

    return "\\" + c;  

}

我們介紹了利用綁定變量和利用esapi兩種方式對(duì)sql注入進(jìn)行防御,我的建議是盡量使用綁定變量的是形式進(jìn)行防注入,安全性能都比較好。

0x02:跨站腳本攻擊

關(guān)于跨站腳本攻擊的防御,我們分析esapi的防御方式。

esapi的防御方式是根據(jù)輸出點(diǎn)的不同在不同的輸出點(diǎn)進(jìn)行相應(yīng)的編碼。我們看一下使用方法:

xss輸出點(diǎn)在html網(wǎng)頁(yè)中  

ESAPI.encoder().encodeForHTML(String input)  

xss輸出點(diǎn)在html屬性中  

ESAPI.encoder().encodeForHTMLAttribute(String input)  

xss輸出點(diǎn)在JavaScript代碼中  

ESAPI.encoder().encodeForJavaScript(String input)  

xss輸出點(diǎn)在CSS代碼中  

ESAPI.encoder().encodeForCSS(String input)  

xss輸出點(diǎn)在VBScript代碼中  

ESAPI.encoder().encodeForVBScript(String input)  

xss輸出點(diǎn)在XPath中  

ESAPI.encoder().encodeForXPath(String input)  

xss輸出點(diǎn)在XML中  

ESAPI.encoder().encodeForXML(String input)  

xss輸出點(diǎn)在XML屬性中  

ESAPI.encoder().encodeForXMLAttribute(String input)  

直接對(duì)url進(jìn)行URL編碼  

ESAPI.encoder().encodeForURL(String input)

如果java輸出在html頁(yè)面,使用如下示例的方法即可。

String username = ESAPI.encoder().encodeForHTML(req.getParameter("name"))

接下來(lái)我們就研究這個(gè)方法的具體實(shí)現(xiàn)。

public String encodeCharacter( char[] immune, Character c ) {  

  

    // check for immune characters  

    if ( containsCharacter(c, immune ) ) {  

        return ""+c;  

    }  

      

    // check for alphanumeric characters  

    String hex = Codec.getHexForNonAlphanumeric(c);  

    if ( hex == null ) {  

        return ""+c;  

    }  

      

    // check for illegal characters  

  

    //ascii碼中的非數(shù)字,字符的編碼,一般為非打印字符,即不能轉(zhuǎn)換的為uncoide的ascii字符,直接替換成\ufffd,顯示的為?  

    if ( ( c <= 0x1f && c != '\t' && c != '\n' && c != '\r' ) || ( c >= 0x7f && c <= 0x9f ) )  

    {  

        hex = REPLACEMENT_HEX;  // Let's entity encode this instead of returning it  

        c = REPLACEMENT_CHAR;  

    }  

      

    // check if there's a defined entity  

    //#惡意字符以實(shí)體的形式輸出  

    String entityName = (String) characterToEntityMap.get(c);  

    if (entityName != null) {  

        return "&" + entityName + ";";  

    }  

      

    // return the hex entity as suggested in the spec,#如果是16進(jìn)制就轉(zhuǎn)換為html16進(jìn)制實(shí)體字符輸出  

    return "&#x" + hex + ";";  

}

惡意字符在js中的編碼大家可以看到使用的是js的十六進(jìn)制編碼或者jsunicode編碼進(jìn)行的編碼。

其實(shí)上面的方法大都是對(duì)字符進(jìn)行html實(shí)體編碼,html十六進(jìn)制編碼,js十六進(jìn)制編碼,jsunicode的編碼和url編碼來(lái)防止惡意標(biāo)簽的執(zhí)行。如果感興趣可以看一下其他的編碼方法,原理大致相同就不在一一介紹。

網(wǎng)站名稱:中安威士:詳解SpringMVC框架中常見漏洞的防御-創(chuàng)新互聯(lián)
文章網(wǎng)址:http://muchs.cn/article44/pdche.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、外貿(mào)建站、小程序開發(fā)、微信公眾號(hào)、標(biāo)簽優(yōu)化搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作