数据库防注入_Spring中依赖注入的四种方式

数据库防注入_Spring中依赖注入的四种方式方法一:摘自https://www.cnblogs.com/yuanchaoyong/p/7243492.htmlFilter拦截包装request->创建过滤器->添加过滤器通过扩展HttpServletRequestWrapper,对HttpServletRequest进行二次包装,覆盖其publicString[]getParameterValues(String…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

方法一:摘自https://www.cnblogs.com/yuanchaoyong/p/7243492.htmlFilter拦截

包装request->创建过滤器->添加过滤器

通过扩展HttpServletRequestWrapper,对HttpServletRequest进行二次包装,覆盖其 public String[] getParameterValues(String name) 方法,在此方法中对各个参数值进行XSS过滤(Spring MVC 部分解析是调用的此方法),实现方式:
1、XssAndSqlHttpServletRequestWrapper 类:

import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {

    HttpServletRequest orgRequest = null;

    public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        orgRequest = request;
    }

    /**
     * 覆盖getParameter方法,将参数名和参数值都做xss & sql过滤。<br/>
     * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/>
     * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
     */
    @Override
    public String getParameter(String name) {
        String value = super.getParameter(xssEncode(name));
        if (value != null) {
            value = xssEncode(value);
        }
        return value;
    }

    /**
     * 覆盖getHeader方法,将参数名和参数值都做xss & sql过滤。<br/>
     * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/>
     * getHeaderNames 也可能需要覆盖
     */
    @Override
    public String getHeader(String name) {

        String value = super.getHeader(xssEncode(name));
        if (value != null) {
            value = xssEncode(value);
        }
        return value;
    }

    /**
     * 将容易引起xss & sql漏洞的半角字符直接替换成全角字符
     *
     * @param s
     * @return
     */
    private static String xssEncode(String s) {
        if (s == null || s.isEmpty()) {
            return s;
        }else{
            s = stripXSSAndSql(s);
        }
        StringBuilder sb = new StringBuilder(s.length() + 16);
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            switch (c) {
                case '>':
                    sb.append(">");// 转义大于号
                    break;
                case '<':
                    sb.append("<");// 转义小于号
                    break;
                case '\'':
                    sb.append("'");// 转义单引号
                    break;
                case '\"':
                    sb.append(""");// 转义双引号
                    break;
                case '&':
                    sb.append("&");// 转义&
                    break;
                case '#':
                    sb.append("#");// 转义#
                    break;
                default:
                    sb.append(c);
                    break;
            }
        }
        return sb.toString();
    }

    /**
     * 获取最原始的request
     *
     * @return
     */
    public HttpServletRequest getOrgRequest() {
        return orgRequest;
    }

    /**
     * 获取最原始的request的静态方法
     *
     * @return
     */
    public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
        if (req instanceof XssAndSqlHttpServletRequestWrapper) {
            return ((XssAndSqlHttpServletRequestWrapper) req).getOrgRequest();
        }

        return req;
    }

    /**
     *
     * 防止xss跨脚本攻击(替换,根据实际情况调整)
     */

    public static String stripXSSAndSql(String value) {
        if (value != null) {
            // NOTE: It's highly recommended to use the ESAPI library and
            // uncomment the following line to
            // avoid encoded attacks.
            // value = ESAPI.encoder().canonicalize(value);
            // Avoid null characters
            /**         value = value.replaceAll("", "");***/
            // Avoid anything between script tags
            Pattern scriptPattern = Pattern.compile("<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid anything in a src="http://www.yihaomen.com/article/java/..." type of e-xpression
//            scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
//            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome </script> tag
            scriptPattern = Pattern.compile("</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome <script ...> tag
            scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid eval(...) expressions
            scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid e-xpression(...) expressions
            scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid javascript:... expressions
            scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid vbscript:... expressions
            scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid onload= expressions
            scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
        }
        return value;
    }

}

Jetbrains全家桶1年46,售后保障稳定

2、XssAndSqlFilter 类: 

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;

public class XssAndSqlFilter implements Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

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

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}

3、web.xml配置

  <!-- 解决xss & sql漏洞 -->
    <filter>
        <filter-name>xssAndSqlFilter</filter-name>
        <filter-class>com.**.commons.filter.XssAndSqlFilter</filter-class>
    </filter>
    <!-- 解决xss & sql漏洞 -->
    <filter-mapping>
        <filter-name>xssAndSqlFilter</filter-name>
        <url-pattern>*</url-pattern>
    </filter-mapping>

 亲测情况:利用easyui的form post提交有效,调用方式:

<form id="resDataAddForm" method="post" enctype="multipart/form-data">

$('#resDataAddForm').form({...
但是当下面的情况时失效,
    <form id="onlinelyAddForm" method="post" class="layui-form">
 

form.on('submit(demo1)', function(data){
		 var data = data.field;
     	$.ajax({
		    type:"post",
	 	    url:"${path}/onlinely/add",
	 	    data:{"name":data.name,"p_reply_email":data.p_reply_email,"p_content":data.p_content},
		    dataType:"json",
		    async:false,
            success: function (result) {
                    ....

方法二:摘自https://blog.csdn.net/zhuangnet/article/details/78744004,为防止删博客,移植过来。

主要思路是:在Spring MVC调用Controller前,通过动态代理和反射机制对Controller的调用进行拦截,并在挡截中对Mehtod参数的值进行XSS过滤替换。

1、 HandlerExecutionChainWrapper.java



import org.springframework.beans.factory.BeanFactory;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.util.HtmlUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by zhanghuaiyu on 2019/6/14.
 */
public class HandlerExecutionChainWrapper extends HandlerExecutionChain {

    private BeanFactory beanFactory;
    private HttpServletRequest request;
    private HandlerMethod handlerWrapper;
    private byte[] lock = new byte[0];

    public HandlerExecutionChainWrapper(HandlerExecutionChain chain,
                                        HttpServletRequest request,
                                        BeanFactory beanFactory) {
        super(chain.getHandler(),chain.getInterceptors());
        this.request = request;
        this.beanFactory = beanFactory;
    }

    @Override
    public Object getHandler() {
        if (handlerWrapper != null) {
            return handlerWrapper;
        }

        synchronized (lock) {
            if (handlerWrapper != null) {
                return handlerWrapper;
            }
            HandlerMethod superMethodHandler = (HandlerMethod)super.getHandler();
            Object proxyBean = createProxyBean(superMethodHandler);
            handlerWrapper = new HandlerMethod(proxyBean,superMethodHandler.getMethod());
            return handlerWrapper;
        }

    }

    /**
     * 为Controller Bean创建一个代理实例,以便用于 实现调用真实Controller Bean前的切面拦截
     * 用以过滤方法参数中可能的XSS注入
     * @param handler
     * @return
     */
    private Object createProxyBean(HandlerMethod handler) {
        try {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(handler.getBeanType());
            Object bean = handler.getBean();
            if (bean instanceof String) {
                bean = beanFactory.getBean((String)bean);
            }
            ControllerXssInterceptor xss = new ControllerXssInterceptor(bean);
            xss.setRequest(this.request);
            enhancer.setCallback(xss);
            return enhancer.create();
        }catch(Exception e) {
            throw new IllegalStateException("为Controller创建代理失败:"+e.getMessage(), e);
        }
    }


    public static class ControllerXssInterceptor implements MethodInterceptor {

        private Object target;
        private HttpServletRequest request;
        private List<String> objectMatchPackages;

        public ControllerXssInterceptor(Object target) {
            this.target = target;
            this.objectMatchPackages = new ArrayList<String>();
            this.objectMatchPackages.add("com.xx");
        }

        public void setRequest(HttpServletRequest request) {
            this.request = request;
        }


        @Override
        public Object intercept(Object obj, Method method, Object[] args,
                                MethodProxy proxy)
                throws Throwable {

            //对Controller的方法参数进行调用前处理
            //过滤String类型参数中可能存在的XSS注入
            if (args != null) {
                for (int i=0;i<args.length;i++) {
                    if (args[i]==null)
                        continue;

                    if (args[i] instanceof String) {
                        args[i] = stringXssReplace((String)args[i]);
                        continue;
                    }

                    for(String pk:objectMatchPackages) {
                        if (args[i].getClass().getName().startsWith(pk)) {
                            objectXssReplace(args[i]);
                            break;
                        }
                    }
                }
            }
            return method.invoke(target, args);
        }

        private String stringXssReplace(String argument) {
            return HtmlUtils.htmlEscape(argument);
        }

        private void objectXssReplace(final Object argument) {
            if (argument == null)
                return;

            ReflectionUtils.doWithFields(argument.getClass(), new ReflectionUtils.FieldCallback(){

                @Override
                public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                    ReflectionUtils.makeAccessible(field);
                    String fv = (String)field.get(argument);
                    if (fv != null) {
                        String nv = HtmlUtils.htmlEscape(fv);
                        field.set(argument, nv);
                    }
                }

            }, new ReflectionUtils.FieldFilter(){

                @Override
                public boolean matches(Field field) {
                    boolean typeMatch = String.class.equals(field.getType());

                    if (request!=null && "GET".equals(request.getMethod())) {
                        boolean requMatch = request.getParameterMap().containsKey(field.getName());
                        return typeMatch && requMatch;
                    }

                    return typeMatch;
                }

            });
        }
    }


}

2、DispatcherServletWrapper.java



import org.springframework.stereotype.Controller;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerExecutionChain;

import javax.servlet.http.HttpServletRequest;

@SuppressWarnings("serial")
public class DispatcherServletWrapper extends DispatcherServlet {

    @Override
    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        HandlerExecutionChain chain = super.getHandler(request);
        Object handler = chain.getHandler();
        if (!(handler instanceof HandlerMethod)) {
            return chain;
        }

        HandlerMethod hm = (HandlerMethod)handler;
        if (!hm.getBeanType().isAnnotationPresent(Controller.class)) {
            return chain;
        }

        //本扩展仅处理@Controller注解的Bean
        return new HandlerExecutionChainWrapper(chain,request,getWebApplicationContext());
    }

}

 3、web.xml

 <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>com.xxxx.commons.filter.DispatcherServletWrapper</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
        <multipart-config>
            <location>/</location>
            <max-file-size>524288000</max-file-size>
            <max-request-size>2097152000</max-request-size>
            <file-size-threshold>0</file-size-threshold>
        </multipart-config>
    </servlet>

亲测上面的问题解决了,但是第一种方式也没删掉。没有全面测试,只是把第一种方式的问题解决了。理论上应该是没有问题的

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/215493.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 防盗链referer详解和解决办法「建议收藏」

    防盗链referer详解和解决办法「建议收藏」防盗链原理:http标准协议中有专门的字段记录referer1、他可以追溯到请求时从哪个网站链接过来的。2、来对于资源文件,可以跟踪到包含显示他的网页地址是什么。因此所有防盗链方法都是基于这个Referer字段1.事情经过在一开始,我打算将其他网站(如:爱奇艺,腾讯)的图片放在自己的网站(http://localhost…)上显示.<imgsrc=”http://pic6…

  • Flume-Kafka-Flume对接Kafka以及Kafka数据分类传输

    Flume-Kafka-Flume对接Kafka以及Kafka数据分类传输Flume对接KafkaFlume日志采集组件;Flume对接kafka主要是为了通过kafka的topic功能,动态的增加或者减少接收的节点,并且Flume要对接多个节点是需要多个channel和sink的会导致内存不够的情况。那么可以实现的场景就是Flume采集日志文件,通过kafka给多给业务线使用。1)配置flume(flume-kafka.conf)#definea1.sources=r1a1.sinks=k1a1.channels=c1#sourcea1

  • JDBC_4数据库连接池[通俗易懂]

    JDBC_4数据库连接池[通俗易懂]数据库连接池JDBC数据库连接池的必要性在使用开发基于数据库的web程序时,传统的模式基本是按照以下步骤:在主程序(如servlet beans)中建立数据库连接进行sql操作断开数据库连接这种模式开发,存在的问题:普通的JDBC数据库连接使用DriverManager来获取,每次向数据库建立连接的时候都要将Connection加载到内存中,再验证用户名和密码(大概花费0.05s-1s),需要数据库连接的时候,就向数据库要求一个,执行完成后再断开。这样的方式将会消耗大量的时间。数据库的

  • Android setContentView流程[通俗易懂]

    Android setContentView流程[通俗易懂]MainActivity继承Activity的流程MainActivity继承至Activityimportandroid.app.Activity;importandroid.os.Bundle;publicclassMainActivityextendsActivity{@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(saved

  • 【转载】什么是堆和栈,它们在哪儿?

    【转载】什么是堆和栈,它们在哪儿?

    2021年11月20日
  • Mac idea2022.01激活码【2021最新】

    (Mac idea2022.01激活码)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号