一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

java解决XSS攻击常用方法代码解析

时间:2021-04-19 编辑:袖梨 来源:一聚教程网

本篇文章小编给大家分享一下java解决XSS攻击常用方法代码解析,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。

前言

在项目验收阶段,通常会对待验收项目做一些安全漏洞的测试,比如接口攻击,并发测试,XSS注入,SQL恶意注入测试,安全越权等操作,这时,就是考验项目的安全方面是否做的足够健壮的时候,本篇对XSS脚本攻击在实际WEB项目中的处理办法,提供2种可实行的方法

xss攻击

XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容

简单说就是说,通过在输入框输入一些js代码,如在账号密码输入框中输入

或者

这样点击提交的时候就会触发alert弹窗,分别弹出 xss 和 @@ 的内容,这里只是做个简单的演示,弹了个窗口,还能存储病毒下载地址到服务端,进入的时候自动下载,或者修改你的cookie啥的,这里感兴趣可以百度查查xss攻击

解决方式一:强制修改html敏感标签内容

这是一种相对容易理解的方式,解决思路就是,当恶意注入的字段中,包含了类似这种html标签时,后台程序代码中强制替换或更改标签内容,这样存入数据库的内容再次返回至页面时,就不会以html的形式进行执行了

下面提供一个工具类

/**
 * xss特殊字符拦截与过滤
 *
 * @author zhangcy
 * @date 2021-04016
 */
public class XssStrUtils {

    /**
     * 滤除content中的危险 HTML 代码, 主要是脚本代码, 滚动字幕代码以及脚本事件处理代码
     * @param content 需要滤除的字符串
     * @return 过滤的结果
     */
    public static String replaceHtmlCode(String content) {
        if (null == content) return null;
        if (0 == content.length()) return "";
        // 需要滤除的脚本事件关键字
        String[] eventKeywords = {
                "onmouseover", "onmouseout", "onmousedown", "onmouseup", "onmousemove", "onclick", "ondblclick",
                "onkeypress", "onkeydown", "onkeyup", "ondragstart", "onerrorupdate", "onhelp", "onreadystatechange",
                "onrowenter", "onrowexit", "onselectstart", "onload", "onunload", "onbeforeunload", "onblur",
                "onerror", "onfocus", "onresize", "onscroll", "oncontextmenu", "alert"
        };
        content = replace(content, " -1) {
            int b = 0;
            String str1, str2, str3, str4, strA, strB;
            str1 = source;
            str2 = str1.toLowerCase();
            str3 = oldStr;
            str4 = str3.toLowerCase();
            if (matchCase) {
                strA = str1;
                strB = str3;
            } else {
                strA = str2;
                strB = str4;
            }
            a = strA.indexOf(strB, findStartPos);
            if (a > -1) {
                b = oldStr.length();
                findStartPos = a + b;
                StringBuffer bbuf = new StringBuffer(source);
                source = bbuf.replace(a, a + b, newStr) + "";
                // 新的查找开始点位于替换后的字符串的结尾
                findStartPos = findStartPos + newStr.length() - b;
            }
        }
        return source;
    }

}

我们用一个实际的接口做一下简单的测试

	@PostMapping("/getAccName")
    public String getAccName(@RequestBody NameParams params){
        String s = XssStrUtils.replaceHtmlCode(params.getName());
        return s;
    }

使用接口工具调一下,

使用这种方式,即使前端恶意注入了某些非法的html标签,经过后端的过滤处理,返回的内容就不会执行html的相关操作事件了

解决方式二:利用过滤器过滤非法html标签

第二种思路,考虑在过滤器中添加对所有请求接口的参数进行参数的拦截过滤,即程序认为的不合法标签都会自动做过滤,至于过滤的规则,可以借助现有的第三方组件,比如spring框架的htmlUtil类,这里使用hutool工具集提供的相关API做处理

导入依赖

		
            cn.hutool
            hutool-all
            5.5.9
        

1、添加自定义过滤器增强包装类

public class XssHttpRequestWrapper extends HttpServletRequestWrapper {

    public XssHttpRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        if(!StringUtils.isEmpty(value)){
            value = HtmlUtil.filter(value);
        }
        return value;
    }

    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if(values!=null){
            for(int i=0;i getParameterMap() {
        Map parameters = super.getParameterMap();
        Map map = new LinkedHashMap<>();
        if(parameters !=null){
            for(String key : parameters.keySet()){
                String[] values = parameters.get(key);
                for(int i=0;i map = JSONUtil.parseObj(body.toString());
        Map result = new LinkedHashMap<>();
        for(String key : map.keySet()){
            Object val = map.get(key);
            if(val instanceof String){
                if(!StringUtils.isEmpty(val.toString())){
                    result.put(key,HtmlUtil.filter(val.toString()));
                }
            }else {
                result.put(key,val);
            }
        }

        String json = JSONUtil.toJsonStr(result);
        ByteArrayInputStream bain = new ByteArrayInputStream(json.getBytes());
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }
            @Override
            public boolean isReady() {
                return false;
            }
            @Override
            public void setReadListener(ReadListener readListener) {

            }
            @Override
            public int read() throws IOException {
                return bain.read();
            }
        };
    }
}

可以理解为,在自定义过滤器中添加上面的增强类,那么所有请求后端的接口都将先走改类的逻辑,参数进行过滤

2、自定义过滤器并注入全局bean

public class XssFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        XssHttpRequestWrapper requestWrapper = new XssHttpRequestWrapper(request);
        filterChain.doFilter(requestWrapper,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

@Configuration
public class XSSFilterRegister {

    @Bean
    public FilterRegistrationBean RegistTest1(){
        //通过FilterRegistrationBean实例设置优先级可以生效
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new XssFilter());//注册自定义过滤器
        bean.setName("flilter");//过滤器名称
        bean.addUrlPatterns("/*");//过滤所有路径
        return bean;
    }

}

仍然使用上面的接口做一下测试

	@PostMapping("/getAccName")
    public String getAccName(@RequestBody NameParams params){
        return "name is : "+ params.getName();
    }

通过这种方式,直接将注入的敏感标签符号去掉,这样确保了入库的数据的安全性,返回给页面的数据就不存在非法html标签问题了

热门栏目