Java添加过滤器过滤xss入侵

Filter过滤器过滤XSS攻击

一.springmvc框架

1.添加自定义过滤器文件XssFilter.java和XssHttpServletRequestWrapper.java
XssFilter.java

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

/**
 * 过滤器
 * Created by adonis on 2020/12/12
 */
public class XssFilter implements Filter{
	
	// 配置信息对象
	public FilterConfig filterConfig;
	private FilterConfig config;
	
	/**
	 * 初始化
	 * 与我们编写的Servlet程序一样,Filter的创建和销毁由WEB服务器负责。 
	 * Web应用程序启动时,Web服务器将创建Filter的实例对象,并调用其init方法,读取web.xml配置,
	 * 完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作。
	 * Filter对象只会创建一次,init方法也只会执行一次。
	 * 开发人员通过init方法的参数,可获得代表当前Filter配置信息的FilterConfig对象。
	 */
	 @Override
	    public void init(FilterConfig filterConfig) throws ServletException {
		 filterConfig = config;
		}
	 	
 	
 	/**
     * 拦截请求
     * 这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL的时候,Servlet过滤器将先执行doFilter方法。
     * FilterChain参数用于访问后续过滤器。
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String enctype = httpRequest.getContentType();
        if(StringUtils.isNotBlank(enctype) && enctype.contains("multipart/form-data")){
        	// 上传文件
        	CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(
    			   httpRequest.getSession().getServletContext());
    		MultipartHttpServletRequest multipartRequest = commonsMultipartResolver.resolveMultipart(httpRequest);
    		XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(multipartRequest);
    		chain.doFilter(xssRequest, response);
        }else{
        	// 普通表单和Ajax
        	XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
        	chain.doFilter(xssRequest, response);
        }
    }
    
    /**
     * 销毁
     * Filter对象创建后会驻留在内存,当Web应用移除或服务器停止时才销毁。在Web容器卸载Filter对象之前被调用。
     * 该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。
     */
    @Override
    public void destroy() {
    	this.filterConfig = null;
	}
	
}


XssHttpServletRequestWrapper.java

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.web.util.HtmlUtils;

/**
 * 用户请求包装类
 * Created by adonis on 2020/12/12
 */
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper{

    public XssHttpServletRequestWrapper(HttpServletRequest request) {  
        super(request);
    }
    
    @Override  
    public String getParameter(String name) {  
        String value = super.getParameter(name);  
        if (value != null) {  
            value = xssEncode(value);  
        }  
        return value;  
    }
    @Override
    public String[] getParameterValues(String name) {
        String[] value = super.getParameterValues(name);
        if(value != null){
            for (int i = 0; i < value.length; i++) {
                value[i] = xssEncode(value[i]);
            }
        }
        return value;
    }
	@Override
    public Map getParameterMap() {
        return super.getParameterMap();
    }
    
	/**
	 * 请求头不过滤
	 */
    @Override  
    public String getHeader(String name) {  
    	return super.getHeader(name);
    }  
    
    /** 
     * 将容易引起注入的关键字的半角字符直接替换成全角字符
     * @param value 过滤前的值
     * @return 过滤后的值
     */  
    private static String xssEncode(String value) {  
        if (value == null || value.isEmpty()) {
            return value;
        }
        // 防SQL注入转义
		value = StringEscapeUtils.escapeSql(value);
		
		// HTML防注入,个人建议使用第三种
        // 1.防HTML注入转义(HtmlUtils工具类,汉字不转义,双引号转义,存在JSON封装需要反转义)
        value = HtmlUtils.htmlEscape(value);
        return value;
    }  
}

2.配置文件web.xml添加Filter配置

<filter>
		<filter-name>xssFilter</filter-name>
		<filter-class>你的文件路径.XssFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>xssFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

二. springboot框架

1.导入依赖库,因为Hutool工具包带有XSS转义的工具类,所以我们要导入Hutool,然后利用Servlet规范提供的请求包装类,定义数据转义功能。

<dependency>
	<groupId>cn.hutool</groupId>
	<artifactId>hutool-all</artifactId>
	<version>5.4.0</version>
</dependency>

2.定义请求包装类

package com.example.emos.wx.config.xss;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.json.JSONUtil;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {

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

    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        if (!StrUtil.hasEmpty(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 < values.length; i++) {
                String value = values[i];
                if (!StrUtil.hasEmpty(value)) {
                    value = HtmlUtil.filter(value);
                }
                values[i] = value;
            }
        }
        return values;
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> parameters = super.getParameterMap();
        Map<String, String[]> map = new LinkedHashMap<>();
        if (parameters != null) {
            for (String key : parameters.keySet()) {
                String[] values = parameters.get(key);
                for (int i = 0; i < values.length; i++) {
                    String value = values[i];
                    if (!StrUtil.hasEmpty(value)) {
                        value = HtmlUtil.filter(value);
                    }
                    values[i] = value;
                }
                map.put(key, values);
            }
        }
        return map;
    }

    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        if (!StrUtil.hasEmpty(value)) {
            value = HtmlUtil.filter(value);
        }
        return value;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        InputStream in = super.getInputStream();
        StringBuffer body = new StringBuffer();
        InputStreamReader reader = new InputStreamReader(in, Charset.forName("UTF-8"));
        BufferedReader buffer = new BufferedReader(reader);
        String line = buffer.readLine();
        while (line != null) {
            body.append(line);
            line = buffer.readLine();
        }
        buffer.close();
        reader.close();
        in.close();

        Map<String, Object> map = JSONUtil.parseObj(body.toString());
        Map<String, Object> resultMap = new HashMap(map.size());
        for (String key : map.keySet()) {
            Object val = map.get(key);
            if (map.get(key) instanceof String) {
                resultMap.put(key, HtmlUtil.filter(val.toString()));
            } else {
                resultMap.put(key, val);
            }
        }
        String str = JSONUtil.toJsonStr(resultMap);
        final ByteArrayInputStream bain = new ByteArrayInputStream(str.getBytes());
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return bain.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {
            }
        };
    }

}

3.创建过滤器

package com.example.emos.wx.config.xss;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter(urlPatterns = "/*")
public class XssFilter implements Filter {

    public void init(FilterConfig config) throws ServletException {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(
                (HttpServletRequest) request);
        chain.doFilter(xssRequest, response);
    }

    @Override
    public void destroy() {
    }
}

4.在boot主类注册过滤器
给SpringBoot主类添加@ServletComponentscan注解。

在这里插入图片描述

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
一、什么是XSS攻击 XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)。这种类型的漏洞由于被黑客用来编写危害性更大的网络钓鱼(Phishing)攻击而变得广为人知。对于跨站脚本攻击,黑客界共识是:跨站脚本攻击是新型的“缓冲区溢出攻击“,而JavaScript是新型的“ShellCode”。 二、XSS漏洞的危害 (1)网络钓鱼,包括盗取各类用户账号; (2)窃取用户cookies资料,从而获取用户隐私信息,或利用用户身份进一步对网站执行操作; (3)劫持用户(浏览器)会话,从而执行任意操作,例如进行非法转账、强制发表日志、发送电子邮件等; (4)强制弹出广告页面、刷流量等; (5)网页挂马; (6)进行恶意操作,例如任意篡改页面信息、删除文章等; (7)进行大量的客户端攻击,如DDoS攻击; (8)获取客户端信息,例如用户的浏览历史、真实IP、开放端口等; (9)控制受害者机器向其他网站发起攻击; (10)结合其他漏洞,如CSRF漏洞,实施进一步作恶; (11)提升用户权限,包括进一步渗透网站; (12)传播跨站脚本蠕虫等; 三、过滤器配置 web.xml配置 XssFilter com.xxx.Filter.XssFilter XssFilter /*

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码小鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值