工作实战之xss攻击防范

目录

前言

一、XSS危害

二、XSS防御

       三、项目实战

1.过滤标签工具类编写

2.网关gateway出,过滤器拦截

   1) 实现步骤

  2)代码实现

总结


前言

跨站脚本攻击(全称Cross Site Scripting,简称为XSS)是指恶意攻击者在Web页面中插入恶意javascript代码(也可能包含html代码),当用户浏览网页之时,嵌入其中Web里面的javascript代码会被执行,从而达到恶意攻击用户的目的
 


一、XSS危害

1.用户的Cookie被获取,其中可能存在Session ID等敏感信息。若服务器端没有做相应防护,攻击者可用对应Cookie登陆服务器。
2.攻击者能够在一定限度内记录用户的键盘输入。
3.攻击者通过CSRF等方式以用户身份执行危险操作。
4.XSS蠕虫。
5.获取用户浏览器信息。
6.利用XSS漏洞扫描用户内网。
 

二、XSS防御

1.标签过滤
2.事件过滤
3.敏感字符过滤
4.设置httponly防止Cookie被获取
5.内容安全策略(CSP)
6.在将不可信数据插入到HTML标签之间时,对这些数据进行HTML Entity编码
7.在将不可信数据插入到HTML属性里时,对这些数据进行HTML属性编码
8.在将不可信数据插入到SCRIPT里时,对这些数据进行SCRIPT编码
9.在将不可信数据插入到Style属性里时,对这些数据进行CSS编码 

三、项目实战

1.过滤标签工具类编写


import org.apache.commons.lang3.StringUtils;
import org.owasp.validator.html.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.MultiValueMapAdapter;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * xss工具类
 *  @author liangxi.zeng
 */
public class XssUtils {

    private static final Logger log = LoggerFactory.getLogger(XssUtils.class);

    private static final String ANTISAMY_SLASHDOT_XML = "antisamy-slashdot-1.4.4.xml";
    private static Policy policy = null;
    private static final Pattern SCRIPT_BETWEEN_PATTERN = Pattern.compile("<[\r\n| | ]*script[\r\n| | ]*>(.*?)", Pattern.CASE_INSENSITIVE);
    private static final Pattern SCRIPT_END_PATTERN = Pattern.compile("", Pattern.CASE_INSENSITIVE);
    private static final Pattern SCRIPT_START_PATTERN = Pattern.compile("<[\r\n| | ]*script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static final Pattern EVAL_PATTERN = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static final Pattern E_XPRESSION_PATTERN = Pattern.compile("e-xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static final Pattern MOCHA_PATTERN = Pattern.compile("mocha[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static final Pattern EXPRESSION_PATTERN = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static final Pattern URL_PATTERN = Pattern.compile("url\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static final Pattern VBSCRIPT_PATTERN = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static final Pattern JAVASCRIPT_PATTERN = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
    private static final Pattern ONLOAD_PATTERN = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static final Pattern ONMOUSEOVER_PATTERN = Pattern.compile("onMouseOver=.*?//", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static final Pattern ONMOUSEOVER_PATTERN_2 = Pattern.compile("onmouseover(.*)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static final Pattern ONMOUSEOVER_PATTERN_3 = Pattern.compile("onmouseover=.*?", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static final Pattern ALERT_PATTERN = Pattern.compile("alert(.*)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    private static String REPLACE_STRING = "";
    private static Pattern script = null;

    static {
        script = Pattern.compile("<[\r\n| | ]*script[\r\n| | ]*>(.*?)", Pattern.CASE_INSENSITIVE);

        log.debug(" start read XSS config file [" + ANTISAMY_SLASHDOT_XML + "]");
        InputStream inputStream = XssUtils.class.getClassLoader().getResourceAsStream(ANTISAMY_SLASHDOT_XML);
        try {
            policy = Policy.getInstance(inputStream);
            log.debug("read XSS config file [" + ANTISAMY_SLASHDOT_XML + "] success");
        } catch (PolicyException e) {
            log.error("read XSS config file [" + ANTISAMY_SLASHDOT_XML + "] fail , reason:", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("close XSS config file [" + ANTISAMY_SLASHDOT_XML + "] fail , reason:", e);
                }
            }
        }
    }

    /**
     * 跨站攻击语句过滤 方法
     *
     * @param paramValue           待过滤的参数
     * @param ignoreParamValueList 忽略过滤的参数列表
     * @return 清理后的字符串
     */
    public static String xssClean(String paramValue, List ignoreParamValueList) {
        AntiSamy antiSamy = new AntiSamy();

        try {
            log.debug("raw value before xssClean: " + paramValue);
            if (isIgnoreParamValue(paramValue, ignoreParamValueList)) {
                log.debug("ignore the xssClean,keep the raw paramValue: " + paramValue);
                return paramValue;
            } else {
                final CleanResults cr = antiSamy.scan(paramValue, policy);
                cr.getErrorMessages().forEach(log::debug);
                String str = cr.getCleanHTML();
                str = stripXSSAndSql(str);
                str = str.replaceAll(""", "\"");
                str = str.replaceAll("&", "&");
//                str = str.replaceAll("'", "'");
//                str = str.replaceAll("'", "'");
//                str = str.replaceAll(" ", "*");
                str = str.replaceAll("<", "<");
                str = str.replaceAll(">", ">");
                log.debug("xss filter value after xssClean" + str);

                return str;
            }
        } catch (ScanException e) {
            log.error("scan failed is [" + paramValue + "]", e);
        } catch (PolicyException e) {
            log.error("antisamy convert failed  is [" + paramValue + "]", e);
        }
        return paramValue;
    }

    /**
     * 过滤形参
     *
     * @param paramValue
     * @param ignoreParamValueList
     * @param param
     * @return
     */
    public static String xssClean(String param,String paramValue, List ignoreParamValueList) {
        if (isIgnoreParamValue(param, ignoreParamValueList)) {
            //虽然过滤固定字段 允许标签 但是关键函数必须处理 不允许出现
            return stripXSSAndSql(paramValue);
        } else {
            return xssClean(paramValue, ignoreParamValueList);
        }
    }

    /**
     * 过滤形参
     *
     * @param httpHeaders
     * @param ignoreParamValueList
     * @return
     */
    public static void xssClean(HttpHeaders httpHeaders, List ignoreParamValueList) {
        if(!CollectionUtils.isEmpty(httpHeaders)) {
            for (Map.Entry> entry : httpHeaders.entrySet()) {
                List paramValueList = entry.getValue();
                String param = entry.getKey();
                if (!CollectionUtils.isEmpty(paramValueList)) {
                    List xssCleanQueryParamList = new ArrayList<>();
                    paramValueList.forEach(paramValue -> {
                        String xssCleanValue = xssClean(param, paramValue, ignoreParamValueList);
                        xssCleanQueryParamList.add(xssCleanValue);
                    });
                    httpHeaders.put(param, xssCleanQueryParamList);
                }
            }
        }
    }

    /**
     * 过滤形参
     *
     * @param queryParamMap
     * @param ignoreParamValueList
     * @return
     */
    public static MultiValueMap xssClean(MultiValueMap queryParamMap, List ignoreParamValueList) {
        if(!CollectionUtils.isEmpty(queryParamMap)) {
            MultiValueMap newQueryParamMap = new MultiValueMapAdapter<>(new HashMap<>());
            for (Map.Entry> entry : queryParamMap.entrySet()) {
                List paramValueList = entry.getValue();
                String param = entry.getKey();
                if (!CollectionUtils.isEmpty(paramValueList)) {
                    List xssCleanQueryParamList = new ArrayList<>();
                    paramValueList.forEach(paramValue -> {
                        String xssCleanValue = xssClean(param, paramValue, ignoreParamValueList);
                        xssCleanQueryParamList.add(xssCleanValue);
                    });
                    newQueryParamMap.put(param, xssCleanQueryParamList);
                } else {
                    newQueryParamMap.put(param,paramValueList);
                }
            }
            return newQueryParamMap;
        }
        return queryParamMap;
    }

    /**
     * xss校验
     *
     * @param value
     * @return
     * @author 杨慕义
     */
    public static String stripXSSAndSql(String value) {
        if (StringUtils.isBlank(value)) {
            return value;
        }
        // Avoid anything between script tags
        value = SCRIPT_BETWEEN_PATTERN.matcher(value).replaceAll(REPLACE_STRING);
        // Remove any lonesome  tag
        value = SCRIPT_END_PATTERN.matcher(value).replaceAll(REPLACE_STRING);
        // Remove any lonesome 
                    
                    

你可能感兴趣的:(项目应用,java,xss,gateway,网关,java,web安全)