對於程式員來說安全防禦,無非從兩個方面考慮,要麼前端要麼後臺。 一、首先從前端考慮過濾一些非法字元。 前端的主控js中,在<textarea> 輸入框標簽中,找到點擊發送按鈕後,追加到聊天panel前 進行過濾Input輸入內容 二、在後臺API服務解決反射型XSS漏洞 thinking:一般來說前 ...
對於程式員來說安全防禦,無非從兩個方面考慮,要麼前端要麼後臺。
一、首先從前端考慮過濾一些非法字元。
前端的主控js中,在<textarea> 輸入框標簽中,
找到點擊發送按鈕後,追加到聊天panel前 進行過濾Input輸入內容
1 // 過濾XSS反射型漏洞 2 filterInputTxt: function (html) { 3 html = html.replace(/(.*<[^>]+>.*)/g,""); // HTML標記 4 html = html.replace(/([\r\n])[\s]+/g, ""); // 換行、空格 5 html = html.replace(/<!--.*-->/g, ""); // HTML註釋 6 html = html.replace(/['"‘’“”!@#$%^&*{}!¥()()×+=]/g, ""); // 非法字元 7 html = html.replace("alert",""); 8 html = html.replace("eval",""); 9 html = html.replace(/(.*javascript.*)/gi,""); 10 if (html === "") { 11 html = "你好"; 12 } 13 return html; 14 }
二、在後臺API服務解決反射型XSS漏洞
thinking:一般來說前端可以過濾一下基本的非法惡意代碼攻擊,如果惡意腳本被請求到服務端啦,那麼就需要請求參數未請求介面前進行過濾一些非法字元。
handle:1、自定義過濾器實現Filter介面
2、在doFilter方法中對request、response進行設置處理
##處理request請求參數。
1 /* 2 * Copyright (C), 2001-2019, xiaoi機器人 3 * Author: han.sun 4 * Date: 2019/2/28 11:39 5 * History: 6 * <author> <time> <version> <desc> 7 * 作者姓名 修改時間 版本號 描述 8 */ 9 package com.eastrobot.robotdev.filter; 10 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletRequestWrapper; 13 import java.util.Map; 14 import java.util.regex.Matcher; 15 import java.util.regex.Pattern; 16 17 /** 18 * 〈一句話功能簡述〉<br> 19 * TODO(解決反射型XSS漏洞攻擊) 20 * 21 * @author han.sun 22 * @version 1.0.0 23 * @since 2019/2/28 11:39 24 */ 25 public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { 26 27 /** 28 * 定義script的正則表達式 29 */ 30 private static final String REG_SCRIPT = "<script[^>]*?>[\\s\\S]*?</script>"; 31 32 /** 33 * 定義style的正則表達式 34 */ 35 private static final String REG_STYLE = "<style[^>]*?>[\\s\\S]*?</style>"; 36 37 /** 38 * 定義HTML標簽的正則表達式 39 */ 40 private static final String REG_HTML = "<[^>]+>"; 41 42 /** 43 * 定義所有w標簽 44 */ 45 private static final String REG_W = "<w[^>]*?>[\\s\\S]*?</w[^>]*?>"; 46 47 private static final String REG_JAVASCRIPT = ".*javascript.*"; 48 49 50 XssHttpServletRequestWrapper(HttpServletRequest request) { 51 super(request); 52 } 53 54 @SuppressWarnings("rawtypes") 55 @Override 56 public Map<String, String[]> getParameterMap() { 57 Map<String, String[]> requestMap = super.getParameterMap(); 58 for (Object o : requestMap.entrySet()) { 59 Map.Entry me = (Map.Entry) o; 60 String[] values = (String[]) me.getValue(); 61 for (int i = 0; i < values.length; i++) { 62 values[i] = xssClean(values[i]); 63 } 64 } 65 return requestMap; 66 } 67 68 @Override 69 public String[] getParameterValues(String paramString) { 70 String[] values = super.getParameterValues(paramString); 71 if (values == null) { 72 return null; 73 } 74 int i = values.length; 75 String[] result = new String[i]; 76 for (int j = 0; j < i; j++) { 77 result[j] = xssClean(values[j]); 78 } 79 return result; 80 } 81 82 @Override 83 public String getParameter(String paramString) { 84 String str = super.getParameter(paramString); 85 if (str == null) { 86 return null; 87 } 88 return xssClean(str); 89 } 90 91 92 @Override 93 public String getHeader(String paramString) { 94 String str = super.getHeader(paramString); 95 if (str == null) { 96 return null; 97 } 98 str = str.replaceAll("[\r\n]", ""); 99 return xssClean(str); 100 } 101 102 /** 103 * [xssClean 過濾特殊、敏感字元] 104 * @param value [請求參數] 105 * @return [value] 106 */ 107 private String xssClean(String value) { 108 if (value == null || "".equals(value)) { 109 return value; 110 } 111 Pattern pw = Pattern.compile(REG_W, Pattern.CASE_INSENSITIVE); 112 Matcher mw = pw.matcher(value); 113 value = mw.replaceAll(""); 114 115 Pattern script = Pattern.compile(REG_SCRIPT, Pattern.CASE_INSENSITIVE); 116 value = script.matcher(value).replaceAll(""); 117 118 Pattern style = Pattern.compile(REG_STYLE, Pattern.CASE_INSENSITIVE); 119 value = style.matcher(value).replaceAll(""); 120 121 Pattern htmlTag = Pattern.compile(REG_HTML, Pattern.CASE_INSENSITIVE); 122 value = htmlTag.matcher(value).replaceAll(""); 123 124 Pattern javascript = Pattern.compile(REG_JAVASCRIPT, Pattern.CASE_INSENSITIVE); 125 value = javascript.matcher(value).replaceAll(""); 126 return value; 127 } 128 129 }
##自定義Filter過濾器。
1 /* 2 * Copyright (C), 2001-2019, xiaoi機器人 3 * Author: han.sun 4 * Date: 2019/2/28 11:38 5 * History: 6 * <author> <time> <version> <desc> 7 * 作者姓名 修改時間 版本號 描述 8 */ 9 package com.eastrobot.robotdev.filter; 10 11 import javax.servlet.*; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 import java.io.IOException; 15 16 /** 17 * 〈在伺服器端對 Cookie 設置了HttpOnly 屬性, 18 * 那麼js腳本就不能讀取到cookie, 19 * 但是瀏覽器還是能夠正常使用cookie〉<br> 20 * TODO(禁用js腳步讀取用戶瀏覽器中的Cookie) 21 * 22 * @author han.sun 23 * @version 1.0.0 24 * @since 2019/2/28 16:38 25 */ 26 public class XssFilter implements Filter { 27 28 @Override 29 public void init(FilterConfig filterConfig) throws ServletException { 30 31 } 32 33 @Override 34 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 35 36 HttpServletRequest req = (HttpServletRequest) request; 37 HttpServletResponse resp = (HttpServletResponse) response; 38 39 // 解決動態腳本獲取網頁cookie,將cookie設置成HttpOnly 40 String sessionId = req.getSession().getId(); 41 resp.setHeader("SET-COOKIE", "JSESSIONID=" + sessionId + "; HttpOnly"); 42 resp.setHeader("x-frame-options", "SAMEORIGIN"); 43 44 chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response); 45 } 46 47 @Override 48 public void destroy() { 49 } 50 }
需要在web.xml文件中添加自定義過濾器映射,讓其起作用
1 <filter> 2 <filter-name>XssEscape</filter-name> 3 <filter-class>com.eastrobot.robotdev.filter.XssFilter</filter-class> 4 </filter> 5 <filter-mapping> 6 <filter-name>XssEscape</filter-name> 7 <url-pattern>/*</url-pattern> 8 </filter-mapping>