中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

中安威士:詳解SpringMVC框架中常見漏洞的防御

發布時間:2020-08-16 13:58:20 來源:ITPUB博客 閱讀:169 作者:數據庫安全專家 欄目:數據庫

下面我們就用利用SpringMVC自帶的數據庫操作類jdbcTemplate舉例。比如下面Dao中有如下的兩個函數。

函數save使用的是綁定變量的形式很好的防止了sql注入,而queryForInt_函數接收id參數直接對sql語句進行了拼接,測試時出現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代碼的開發過程中,我們盡量避免使用拼接sql語句的形式去執行數據庫語句。如果需要使用拼接sql語句的形式進行數據庫查詢,那么OWASP提供了一個防御sql注入的Esapi包,這個包中的encodeForSQL方法能對sql注入進行很好的防御。


接著我們就分析下這個encodeForSQL方法。

首先我們介紹這個方法的使用,使用時調用如下,不同的數據庫使用不到的方法。


//防止Oracle注入  

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

//防止mysql注入  

ESAPI.encoder().encodeForSQL(new MySQLCodec(Mode.STANDARD),queryparam) //Mode.STANDARK為標準的防注入方式,mysql一般用使用的是這個方式  

//防止DB2注入  

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

  

  

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

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函數做了什么防御。具體函數過

程就不跟蹤了,直接分析最后調用了哪個方法。根據代碼可知最后調用的是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函數是不進行驗證的字符串白名單,Codec.getHexForNonAlphanumeric函數查找字符傳中是否有16進制,沒有返回空值。


而encodeCharacterANSI和encodeCharacterMySQL才是防御的重點,我們看一下這兩個函數的不同,如果選擇的我們選擇是Mode.ANSi模式,則字符串則進入下面的函數,可以看到這個函數對單撇號和雙撇號進行了轉義。


private String encodeCharacterANSI( Character c ) {  

    if ( c == '\'' )  

        return "\'\'";  

    if ( c == '\"' )  

        return "";  

    return ""+c;  

}


如果選擇的是Mode.STANDARD模式,則字符串 則進入下面的函數,可以看到這個函數對單撇號和雙撇號、百分號、反斜線等更多的符號進行了轉換,所以使用時推薦使用標準模式。



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兩種方式對sql注入進行防御,我的建議是盡量使用綁定變量的是形式進行防注入,安全性能都比較好。


0x02:跨站腳本攻擊


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

esapi的防御方式是根據輸出點的不同在不同的輸出點進行相應的編碼。我們看一下使用方法:


xss輸出點在html網頁中  

ESAPI.encoder().encodeForHTML(String input)  

xss輸出點在html屬性中  

ESAPI.encoder().encodeForHTMLAttribute(String input)  

xss輸出點在JavaScript代碼中  

ESAPI.encoder().encodeForJavaScript(String input)  

xss輸出點在CSS代碼中  

ESAPI.encoder().encodeForCSS(String input)  

xss輸出點在VBScript代碼中  

ESAPI.encoder().encodeForVBScript(String input)  

xss輸出點在XPath中  

ESAPI.encoder().encodeForXPath(String input)  

xss輸出點在XML中  

ESAPI.encoder().encodeForXML(String input)  

xss輸出點在XML屬性中  

ESAPI.encoder().encodeForXMLAttribute(String input)  

直接對url進行URL編碼  

ESAPI.encoder().encodeForURL(String input)


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


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


接下來我們就研究這個方法的具體實現。


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碼中的非數字,字符的編碼,一般為非打印字符,即不能轉換的為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  

    //#惡意字符以實體的形式輸出  

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

    if (entityName != null) {  

        return "&" + entityName + ";";  

    }  

      

    // return the hex entity as suggested in the spec,#如果是16進制就轉換為html16進制實體字符輸出  

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

}


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


其實上面的方法大都是對字符進行html實體編碼,html十六進制編碼,js十六進制編碼,jsunicode的編碼和url編碼來防止惡意標簽的執行。如果感興趣可以看一下其他的編碼方法,原理大致相同就不在一一介紹。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

平远县| 玛曲县| 麻江县| 温泉县| 乌海市| 武定县| 方正县| 长宁县| 岳普湖县| 桃源县| 罗城| 建瓯市| 柘荣县| 蒙山县| 忻城县| 麻江县| 达孜县| 岐山县| 松桃| 红安县| 乌拉特前旗| 平顺县| 黔江区| 舞阳县| 隆德县| 姜堰市| 赤水市| 涿鹿县| 池州市| 龙川县| 丘北县| 靖江市| 泰州市| 乾安县| 大渡口区| 镇原县| 海原县| 大埔区| 昌都县| 勐海县| 台前县|