xss攻擊防范轉義處理


1:xss攻擊原理說明

  這里不再詳細參數,簡單說一下,就是前端提交了可執行的js等腳本,存儲到數據庫,頁面再次加載時獲取到該腳本執行了腳本內容就發生了腳本注入。

 

2:處理辦法

  轉義提交字符

 

3:代碼邏輯原理

  利用過濾器,重寫參數獲取方法,對參數進行轉義。

 

4:代碼

 

  4.1 xss轉義包裝類(重寫getParameter、getParameterValues、getParameterMap

package com.zxy.product.system.web.converter;

import cn.hutool.core.util.EscapeUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.safety.Whitelist;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {

    public static final String HEADER_XSS_FILTER = "xssFilter";

    public static final String[] EMPTY_STRING_ARRAY = new String[0];

    /**
     * 安全xss處理,不影響普通標簽輸出。
     */
    public static final String XSS_FILTER_FULL_ANGLE = "1";
    /**
     * html轉義
     */
    public static final String XSS_FILTER_ESCAPE_HTML = "2";


    /**
     * Constructs a request object wrapping the given request.
     *
     * @param request The request to wrap
     * @throws IllegalArgumentException if the request is null
     */
    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }


    /**
     * 全角字符轉義
     *
     * @param str 待轉義
     * @return 轉義結果
     * @author wulingming
     * @date 2021/9/9 17:07
     **/
    public static String escapeFullAngle(String str) {
        if (str == null || str.length() == 0) {
            return str;
        } else {
            return str.replace("<", "《").replace(">", "》");
        }
    }

    public static String escapeHtml4(String str) {
        if (str == null || str.length() == 0) {
            return str;
        } else {
            return EscapeUtil.escapeHtml4(str);
        }
    }

    private static String escape(String value) {
        return escape(value, null);
    }

    private static String escape(String value, String headerXssFilter) {
        if (XSS_FILTER_ESCAPE_HTML.equals(headerXssFilter)) {
            //html轉義
            return escapeHtml4(value);
        } else {
            //使用Jsoup防止XSS攻擊。還有一種方式是hutol(優缺點,部分字符可能不輸出)
            return clean(value);
        }
    }


    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        if (value == null || value.length() == 0) {
            return null;
        }
        String headerXssFilter = super.getHeader(HEADER_XSS_FILTER);
        return escape(value, headerXssFilter);
    }


    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if (values == null || values.length == 0) {
            return values;
        }

        String headerXssFilter = super.getHeader(HEADER_XSS_FILTER);

        return Stream.of(values).map(value -> escape(value, headerXssFilter)).collect(Collectors.toList())
                .toArray(EMPTY_STRING_ARRAY);
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> parameterMap = super.getParameterMap();
        if (parameterMap == null || parameterMap.isEmpty()) {
            return parameterMap;
        }

        String headerXssFilter = super.getHeader(HEADER_XSS_FILTER);

        return parameterMap.keySet().stream().filter(Objects::nonNull)
                .collect(Collectors.toMap(key -> key, key -> {
                    String[] values = parameterMap.get(key);
                    if (values == null || values.length == 0) {
                        return EMPTY_STRING_ARRAY;
                    } else {
                        return Stream.of(values).map(value -> escape(value, headerXssFilter))
                                .collect(Collectors.toList()).toArray(EMPTY_STRING_ARRAY);
                    }
                }));
    }


    /**
     * 使用自帶的basicWithImages 白名單
     * 允許的便簽有a,b,blockquote,br,cite,code,dd,dl,dt,em,i,li,ol,p,pre,q,small,span,
     * strike,strong,sub,sup,u,ul,img
     * 以及a標簽的href,img標簽的src,align,alt,height,width,title屬性
     */
    private static final Whitelist whitelist = Whitelist.relaxed();
    /**
     * 配置過濾化參數,不對代碼進行格式化
     */
    private static final Document.OutputSettings outputSettings = new Document.OutputSettings()
            .prettyPrint(false);

    static {
        // 富文本編輯時一些樣式是使用style來進行實現的,比如紅色字體 style="color:red;"
        whitelist.addAttributes(":all", "style");

        //使用相對路徑,比如:img標簽
        whitelist.preserveRelativeLinks(true);

    }

    /**
     * 安全xss處理,不影響普通標簽輸出。
     *
     * @param text 原始文本
     * @return 清理后的文本
     * @author wulingming
     **/
    public static String clean(String text) {
        //baseUri可以隨便填寫,因為使用了相對路徑 preserveRelativeLinks(true)
        return Jsoup.clean(text, "https://ilearning.csair.com/", whitelist, outputSettings);
    }

}

 

 

 

  4.2 xss過濾器配置

 

/**
 * xss攻擊防范處理
 * @author wulingming
 * @date 2021/9/9 16:32
 **/
@WebFilter(urlPatterns = "/*", filterName = "xssFilter")
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 {
        XssHttpServletRequestWrapper req=new XssHttpServletRequestWrapper((HttpServletRequest)request);
        chain.doFilter(req,response);

    }
}

  4.3 springboot 啟動類配置過濾器掃描

@ServletComponentScan

 

getParameter


免責聲明!

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



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