解決反射型XSS漏洞攻擊


對於程序員來說安全防御,無非從兩個方面考慮,要么前端要么后台。

一、首先從前端考慮過濾一些非法字符。

前端的主控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() {
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM