跨站腳本就是在url上帶上惡意的js關(guān)鍵字然后腳本注入了,跨站偽造用戶請求就是沒有經(jīng)過登陸,用超鏈接或者直接url上敲地址進入系統(tǒng),類似于sql注入這些都是安全漏洞。
1、參數(shù)化查詢預(yù)處理,如java使用PreparedStatement()處理變量。
2、轉(zhuǎn)義敏感字符及字符串(SQL的敏感字符包括“exec”,”xp_”,”sp_”,”declare”,”Union”,”cmd”,”+”,”//”,”..”,”;”,”‘”,”--”,”%”,”0x”,”><=!-*/()|”,和”空格”)。
3、屏蔽出錯信息:阻止攻擊者知道攻擊的結(jié)果。
4、在服務(wù)端正式處理之前對提交數(shù)據(jù)的合法性(合法性檢查主要包括三項:數(shù)據(jù)類型,數(shù)據(jù)長度,敏感字符的校驗)進行檢查等,在確認(rèn)客戶端的輸入合法之前,服務(wù)端拒絕進行關(guān)鍵性的處理操作。
一般性建議:轉(zhuǎn)義或過濾客戶端提交的危險字符,客戶端提交方式包含GET、POST、COOKIE、User-Agent、Referer、Accept-Language等,其中危險字符如下:
建議轉(zhuǎn)義或過濾以下字符:
[1] |(豎線符號)
[2] & (& 符號)
[3];(分號)
[4] $(美元符號)
[5] %(百分比符號)
[6] @(at 符號)
[7] '(單引號)
[8] ""(引號)
[9] \'(反斜杠轉(zhuǎn)義單引號)
[10] \""(反斜杠轉(zhuǎn)義引號)
[11] <>(尖括號)
[12] ()(括號)
[13] +(加號)
[14] CR(回車符,ASCII 0x0d)
[15] LF(換行,ASCII 0x0a)
[16] ,(逗號)
[17] \(反斜杠)
[18] (空格)
[19] . (點號)
過濾以下關(guān)鍵字、標(biāo)簽:alert、img、script、document、document.title、document.write、eval、prompt、onclick、onerror、onmouseenter、onreadystatechange、confirm、javascript、String.fromCharCode、onload、DYNSRC、LOWSRC、behavior、vbscript、msgbox、mocha、livescript、。
開發(fā)語言的建議:
[1]嚴(yán)格控制輸入:
Asp:request
Aspx:Request.QueryString、Form、Cookies、SeverVaiables等
Php:$_GET、$_POST、$_COOKIE、$_SERVER、$_GlOBAL、$_REQUEST等
Jsp:request.getParameter、request.getCookies 等
客戶端提交的變量一般從以上函數(shù)獲得,嚴(yán)格限制提交的數(shù)據(jù)長度、類型、字符集。
[2]嚴(yán)格控制輸出:
HtmlEncode:對一段指定的字符串應(yīng)用HTML編碼。
UrlEncode:對一段指定的字符串URL編碼。
XmlEncode:將在XML中使用的輸入字符串編碼。
XmlAttributeEncode:將在XML屬性中使用的輸入字符串編碼
escape:函數(shù)可對字符串進行編碼
decodeURIComponent:返回統(tǒng)一資源標(biāo)識符的一個已編碼組件的非編碼形式。
encodeURI:將文本字符串編碼為一個有效的統(tǒng)一資源標(biāo)識符 (URI)。" "get型xss:
方案一、存在漏洞的頁面加驗證碼或手機短信驗證
方案二、檢測HTTP請求中的訪問來源是否可信,對http頭中的referer進行過濾,只允許本域站點
方案三、一次性令牌Token
添加一個參數(shù)Token,其值是隨機的。這樣攻擊者因為不知道Token而無法構(gòu)造出合法的請求進行攻擊。實現(xiàn)方法:首先服務(wù)器端要以某種策略生成隨機字符串,作為令牌(token),保存在 Session 里。然后在發(fā)出請求的頁面,把該令牌以隱藏域一類的形式,與其他信息一并發(fā)出。在接收請求的頁面,把接收到的信息中的令牌與 Session 中的令牌比較,只有一致的時候才處理請求,否則拒絕請求或者要求用戶重新登陸驗證身份。
Token 使用原則:
Token要足夠隨機————只有這樣才算不可預(yù)測
Token是一次性的,即每次請求成功后要更新Token————這樣可以增加攻擊難度,增加預(yù)測難度
Token要注意保密性————敏感操作使用post,防止Token出現(xiàn)在URL中
方案四、臨時cookie:對會話進行時效限制,將持久化的授權(quán)方法(例如cookie或者HTTP授權(quán))切換為短時或瞬時的授權(quán)方法
方案五、session標(biāo)記隨機生成;確認(rèn)已有的session標(biāo)記無法被二次使用
方案六、過濾用戶輸入,例如論壇、博客等,不允許發(fā)布含有站內(nèi)操作URL的鏈接(作用有限,因為可以通過qq、第三方網(wǎng)站進行發(fā)布,圖片形式會自動加載等)
方案七、根據(jù)不可預(yù)測性原則,我們可以對參數(shù)進行加密從而防止CSRF攻擊。"
已解密的登錄請求 對諸如用戶名、密碼和信用卡號之類的敏感輸入字段進行加密傳遞
會話定置 "COOKIE中的登陸前JSESSIONID與登陸后JESSIONID不能相同
例如在登錄頁面上加上一段代碼:
request.getSession().invalidate() ; //清空sessionif (request.getCookies()!=null) { Cookie cookie = request.getCookies()[0]; // 獲取cookie cookie.setMaxAge(0); // 讓cookie過期}"
[1]嚴(yán)格判斷上傳文件的類型,設(shè)置上傳文件白名單,只允許上傳指定類型的文件。
[2]禁止在上傳目錄下執(zhí)行腳本。
[3]上傳文件的目錄必須是http請求無法直接訪問到的。如果需要訪問的,必須上傳到其他(和web服務(wù)器不同的)域名下,并設(shè)置該目錄為不解析jsp等腳本語言的目錄。
[4]上傳文件要保存的文件名和目錄名由系統(tǒng)根據(jù)時間生成,不允許用戶自定義。
[5]圖片上傳,要通過處理(縮略圖、水印等),無異常后才能保存到服務(wù)器。"
"升級Jquery到1.7版本以上,或在js中修改如下行,quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/
修改為:quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/"
修改web.xml,增加如下配置
<login-config> <!-- Authorization setting for SSL --> <auth-method>CLIENT-CERT</auth-method> <realm-name>Client Cert Users-only Area</realm-name> <auth-method>BASIC</auth-method> </login-config> <security-constraint> <!-- Authorization setting for SSL --> <web-resource-collection> <web-resource-name>SSL</web-resource-name> <url-pattern>/oa/login.jsp</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <!-- 禁止不安全的http方法 --> <security-constraint> <web-resource-collection> <web-resource-name>fortune</web-resource-name> <url-pattern>/*</url-pattern> <http-method>PUT</http-method> <http-method>DELETE</http-method> <http-method>HEAD</http-method> <http-method>OPTIONS</http-method> <http-method>TRACE</http-method> </web-resource-collection> <auth-constraint></auth-constraint> </security-constraint>
對每個錯誤的登錄嘗試發(fā)出相同的錯誤消息,不管是哪個字段發(fā)生錯誤,特別是用戶名或密碼字段錯誤。
文件備份 "刪除備份文件。
.arc/.bac/.backup/.bak/.bck/.copy/.old/.orig/.sav/.save/.saved/.swp/.temp/.test/.tmp/.txt"。
以下是我自己寫的一份攔截器,里面可以實現(xiàn)對http請求的參數(shù)攔截,解決跨站腳本注入:
package com.asiainfo.aiga.common.filter;import java.io.IOException;import java.util.Enumeration;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang3.StringUtils;public class XSSCheckFilter implements Filter{ private FilterConfig config; private static String errorPath;//出錯跳轉(zhuǎn)的目的地 private static String[] excludePaths;//不進行攔截的url private static String[] safeless = { "<script", //需要攔截的JS字符關(guān)鍵字 "</script", "<iframe", "</iframe", "<frame", "</frame", "set-cookie", "%3cscript", "%3c/script", "%3ciframe", "%3c/iframe", "%3cframe", "%3c/frame", "src=\"javascript:", "<body", "</body", "%3cbody", "%3c/body", "alert", "script", "document", "document.title", "document.write", "eval", "prompt", "onreadystatechange", "javascript", "msgbox" //"<", //">", //"</", //"/>", //"%3c", //"%3e", //"%3c/", //"/%3e" }; public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException { Enumeration params = req.getParameterNames(); HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; boolean isSafe = true; String requestUrl = request.getRequestURI(); if (isSafe(requestUrl)) { requestUrl = requestUrl.substring(requestUrl.indexOf("/")); if (!excludeUrl(requestUrl)) { while (params.hasMoreElements()) { String cache = req.getParameter((String) params.nextElement()); if (StringUtils.isNotBlank(cache)) { if (!isSafe(cache)) { isSafe = false; break; } } } } } else { isSafe = false; } if (!isSafe) { request.setAttribute("msg", "There is some illegal characters in paramters."); request.getRequestDispatcher(errorPath).forward(request, response); return; } else { String referer = request.getHeader("referer"); if (!("/index.jsp".equals(request.getServletPath()) || "/refresh.jsp".equals(request.getServletPath()))) { if(request.getServletPath()!=null&&request.getServletPath().endsWith(".action")){ }else if (referer == null || !referer.contains(request.getServerName())) { System.out.println("跨站請求偽造"); //轉(zhuǎn)到一個錯誤的圖片 request.getRequestDispatcher(errorPath).forward(request, response); } } } filterChain.doFilter(req, resp); } private static boolean isSafe(String str) { if (StringUtils.isNotBlank(str)) { for (String s : safeless) { String[] strs = str.split("/"); for (String urlStr : strs) { if (s.equals(urlStr.toLowerCase())) { return false; } } } } return true; } private boolean excludeUrl(String url) { if (excludePaths != null && excludePaths.length > 0) { for (String path : excludePaths) { if (url.toLowerCase().equals(path)) { return true; } } } return false; } public void destroy() { } public void init(FilterConfig config) throws ServletException { this.config = config; errorPath = config.getInitParameter("errorPath"); String excludePath = config.getInitParameter("excludePaths"); if (StringUtils.isNotBlank(excludePath)) { excludePaths = excludePath.split(","); } }}