對於程序員來說安全防御,無非從兩個方面考慮,要么前端要么后台。
一、首先從前端考慮過濾一些非法字符。
前端的主控js中,在<textarea> 輸入框標簽中,
找到點擊發送按鈕后,追加到聊天panel前 進行過濾Input輸入內容
// 過濾XSS反射型漏洞 filterInputTxt: function (html) { html = html.replace(/(.*<[^>]+>.*)/g,""); // HTML標記 html = html.replace(/([\r\n])[\s]+/g, ""); // 換行、空格 html = html.replace(/<!--.*-->/g, ""); // HTML注釋 html = html.replace(/['"‘’“”!@#$%^&*{}!¥()()×+=]/g, ""); // 非法字符 html = html.replace("alert",""); html = html.replace("eval",""); html = html.replace(/(.*javascript.*)/gi,""); if (html === "") { html = "你好"; } return html; }
二、在后台API服務解決反射型XSS漏洞
thinking:一般來說前端可以過濾一下基本的非法惡意代碼攻擊,如果惡意腳本被請求到服務端啦,那么就需要請求參數未請求接口前進行過濾一些非法字符。
handle:1、自定義過濾器實現Filter接口
2、在doFilter方法中對request、response進行設置處理
##處理request請求參數。
package com.eastrobot.robotdev.filter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 〈一句話功能簡述〉<br> * TODO(解決反射型XSS漏洞攻擊) * * @author han.sun * @version 1.0.0 * @since 2019/2/28 11:39 */ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { /** * 定義script的正則表達式 */ private static final String REG_SCRIPT = "<script[^>]*?>[\\s\\S]*?</script>"; /** * 定義style的正則表達式 */ private static final String REG_STYLE = "<style[^>]*?>[\\s\\S]*?</style>"; /** * 定義HTML標簽的正則表達式 */ private static final String REG_HTML = "<[^>]+>"; /** * 定義所有w標簽 */ private static final String REG_W = "<w[^>]*?>[\\s\\S]*?</w[^>]*?>"; private static final String REG_JAVASCRIPT = ".*javascript.*"; XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); } @SuppressWarnings("rawtypes") @Override public Map<String, String[]> getParameterMap() { Map<String, String[]> requestMap = super.getParameterMap(); for (Object o : requestMap.entrySet()) { Map.Entry me = (Map.Entry) o; String[] values = (String[]) me.getValue(); for (int i = 0; i < values.length; i++) { values[i] = xssClean(values[i]); } } return requestMap; } @Override public String[] getParameterValues(String paramString) { String[] values = super.getParameterValues(paramString); if (values == null) { return null; } int i = values.length; String[] result = new String[i]; for (int j = 0; j < i; j++) { result[j] = xssClean(values[j]); } return result; } @Override public String getParameter(String paramString) { String str = super.getParameter(paramString); if (str == null) { return null; } return xssClean(str); } @Override public String getHeader(String paramString) { String str = super.getHeader(paramString); if (str == null) { return null; } str = str.replaceAll("[\r\n]", ""); return xssClean(str); } /** * [xssClean 過濾特殊、敏感字符] * @param value [請求參數] * @return [value] */ private String xssClean(String value) { if (value == null || "".equals(value)) { return value; } Pattern pw = Pattern.compile(REG_W, Pattern.CASE_INSENSITIVE); Matcher mw = pw.matcher(value); value = mw.replaceAll(""); Pattern script = Pattern.compile(REG_SCRIPT, Pattern.CASE_INSENSITIVE); value = script.matcher(value).replaceAll(""); Pattern style = Pattern.compile(REG_STYLE, Pattern.CASE_INSENSITIVE); value = style.matcher(value).replaceAll(""); Pattern htmlTag = Pattern.compile(REG_HTML, Pattern.CASE_INSENSITIVE); value = htmlTag.matcher(value).replaceAll(""); Pattern javascript = Pattern.compile(REG_JAVASCRIPT, Pattern.CASE_INSENSITIVE); value = javascript.matcher(value).replaceAll(""); return value; } }
##自定義Filter過濾器。
package com.eastrobot.robotdev.filter; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * 〈在服務器端對 Cookie 設置了HttpOnly 屬性, * 那么js腳本就不能讀取到cookie, * 但是瀏覽器還是能夠正常使用cookie〉<br> * TODO(禁用js腳步讀取用戶瀏覽器中的Cookie) */ @WebFilter(filterName="xssFilter",urlPatterns= {"/*"}) @Order(FilterRegistrationBean.LOWEST_PRECEDENCE) public class XssFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; // 解決動態腳本獲取網頁cookie,將cookie設置成HttpOnly String sessionId = req.getSession().getId(); resp.setHeader("SET-COOKIE", "JSESSIONID=" + sessionId + "; HttpOnly"); resp.setHeader("x-frame-options", "SAMEORIGIN"); chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response); } @Override public void destroy() { } }