数据库防注入_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)


相关推荐

  • Visual Studio——使用多字节字符集与使用Unicode字符集

    Visual Studio——使用多字节字符集与使用Unicode字符集vs配置选项“使用多字节字符集”和“使用Unicode字符集”的区别VS集成开发环境,字符集选择“使用多字节字符集”和“使用Unicode字符集”的直接区别就是:编译器是否增加了宏定义——UNICODE。当选择“使用Unicode字符集”时,编译器会增加宏定义——UNICODE;而选择“使用多字节字符集”时,编译器则不会增加宏定义——UNICODE。而是否增加了宏定义UNICODE,则…

    2022年10月22日
  • VMware虚拟机安装Ubuntu系统步骤详解

    VMware虚拟机安装Ubuntu系统步骤详解Ubuntu系统介绍VMware安装Ubuntu步骤一.Ubuntu系统的下载二.VMwareworkstation的下载安装三.配置Ubuntu虚拟机系统VMware安装Ubuntu系统Ubuntu系统介绍Ubuntu是一个以桌面应用为主的Linux操作系统。作为Linux发行版中的后起之秀,UbuntuLinux在短短几年时间里就成长为从L…

  • python中的float类型计算精度不高的问题(已解决)

    python中的float类型计算精度不高的问题(已解决)说的可能比较啰嗦。在洛谷P2181对角线问题中,按照高中所学的组合数可推答案为Cn4(该题题解中有详细过程,这里不多赘述),问题在本文中并不重要。但题中有一个有意思的点,就是题目的答案是非常大

  • Android开发——RelativeLayout.LayoutParams的使用「建议收藏」

    Android开发——RelativeLayout.LayoutParams的使用「建议收藏」前言在日常的Android开发当中,我们少不了需要动态改变控件在RelativeLayout界面的位置。那么我们就需要使用到RelativeLayout.LayoutParams。RelativeLayout.LayoutParamsRelativeLayout.LayoutParams是一个RelativeLayout的布局参数,我们改变控件的就需要使用到。初始化//包裹内容Rel…

  • Java自学视频整理(持续更新中…)

    Java自学视频整理(持续更新中…)1.Java基础视频 《张孝祥JAVA视频教程》完整版[RMVB](东西网)历经5年锤炼(史上最适合初学者入门的Java基础视频)(传智播客)张孝祥2010年贺岁视频:Java高新技术(传智播客)Java多线程与并发库高级应用(传智播客)尚学堂JAVA视频下载大全(持续更新中…请关注!)(尚学堂)《动力节点,王勇JAVA系列视频教程》(东西网)张孝祥Java高新技术

  • k8s(六)k8s生命周期和调度[通俗易懂]

    k8s(六)k8s生命周期和调度[通俗易懂]k8s概述创建和终止初始化容器钩子函数容器探测重启策略概述• 我们一般将Pod对象从创建到终止的这段时间范围称为Pod的生命周期,它主要包含下面的过程:Pod创建过程。运行初始化容器(init container)过程。运行主容器(main container):容器启动后钩子(post start)、容器终止前钩子(pre stop)。容器的存活性探测(liveness probe)、就绪性探测(readiness probe)。Pod终止过程。在整个生命周期中,Pod会出

发表回复

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

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