springboot清除字符串前后空格与防xss攻击方法

目录
  • springboot清除字符串前后空格与防xss攻击
    • 一、查看WebMvcAutoConfiguration.class中的方法源码
    • 二、自定义属性编辑器
    • 三、创建WebBindingInitializerConfiguration类
  • springboot去除参数中前后空格说明
    • 一、 需求
    • 二、 解决方法
    • 三、 完美解决

springboot清除字符串前后空格与防xss攻击

一、查看WebMvcAutoConfiguration.class中的方法源码

protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
    try {
        //从容器中获取
        return (ConfigurableWebBindingInitializer)this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
    } catch (NoSuchBeanDefinitionException ex) {
      return super.getConfigurableWebBindingInitializer();
    }

可以发现ConfigurableWebBindingInitializer是从容器(beanFactory)中获取到的,所以我们可以配置一个

ConfigurableWebBindingInitializer来替换默认的,只需要在容器中添加一个我们自定义的转换器即可。

当我们创建了自己的ConfigurableWebBindingInitializer这个Bean,Spring boot就会自动使用它来配置Spring MVC实现参数的类型转换。

二、自定义属性编辑器

/**
     *
     * @description 与spring mvc的@InitBinder结合 用于防止XSS攻击
     */
     class StringEscapeEditor extends PropertyEditorSupport {
        /** 转义HTML */
        private boolean escapeHTML;
        /** 转义javascript */
        private boolean escapeJavaScript;
        /** 是否将空字符串转换为null */
        private final boolean emptyAsNull;
        /** 是否去掉前后空格 */
        private final boolean trimmed;
        public StringEscapeEditor() {
            this(true,true,false,true);
        }
        public StringEscapeEditor(boolean escapeHTML, boolean escapeJavaScript) {
            this(true,true,escapeHTML,escapeJavaScript);
        }
        public StringEscapeEditor(boolean emptyAsNull,boolean trimmed, boolean escapeHTML, boolean escapeJavaScript) {
            super();
            this.emptyAsNull = emptyAsNull;
            this.trimmed = trimmed;
            this.escapeHTML = escapeHTML;
            this.escapeJavaScript = escapeJavaScript;
        }
        @Override
        public String getAsText() {
            Object value = getValue();
            if(Objects.nonNull(value))
            {
                return value.toString();
            }
            return value != null ? value.toString() : null;
        }
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            String value = text;
            if (value == null || emptyAsNull && text.isEmpty()) {
                //do nothing
            } else if (trimmed) {
                //去字符传参数前后空格
                value = value.trim();
            }
            if (escapeHTML) {
                //HTML转义(防止XSS攻击)
                //HtmlUtils.htmlEscape 默认的是ISO-8859-1编码格式,会将中文的某些符号进行转义。
                //如果不想让中文符号进行转义请使用UTF-8的编码格式。例如:HtmlUtils.htmlEscape(text, "UTF-8")
                value = HtmlUtils.htmlEscape(value, "UTF-8");
            }
            if (escapeJavaScript) {
                //javascript转义(防止XSS攻击)
                value = JavaScriptUtils.javaScriptEscape(value);
            }
            setValue(value);
        }
    }

三、创建WebBindingInitializerConfiguration类

加上@Bean注解,交给spring容器管理。

@Configuration
public class WebBindingInitializerConfiguration {
    @Bean
    public ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
        ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
        FormattingConversionService conversionService = new DefaultFormattingConversionService();
        //we can add our custom converters and formatters
        //conversionService.addConverter(...);
        //conversionService.addFormatter(...);
        initializer.setConversionService(conversionService);
        //we can set our custom validator
        //initializer.setValidator(....);
        //here we are setting a custom PropertyEditor
        initializer.setPropertyEditorRegistrar(propertyEditorRegistry -> {
            propertyEditorRegistry.registerCustomEditor(String.class,
                    new StringEscapeEditor());
        });
        return initializer;
    }
}

springboot去除参数中前后空格说明

一、 需求

使用SpringBoot使用过滤器去除@RequestBody参数两端的空格;一般我们去普通的请求我们都会对请求参数进行验证。

Java也提供了@notNull和@notBlank这种验证方式,但是对@RequestBody 这种只能验证是不是非空,对数据两端的空格未进行处理,同时大家也不想遍历一遍参数然后再处理再封装到对象中,正好项目中有这个需要,所以就参考别的做了Post请求中针对application/json格式的有@RequestBody注解的参数进行了去空格处理

二、 解决方法

2.1 新建一个过滤器

@Component
@WebFilter(urlPatterns = "/**", filterName = "ParamsFilter", dispatcherTypes = DispatcherType.REQUEST)
public class ParamsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        ParameterRequestWrapper parmsRequest = new ParameterRequestWrapper((HttpServletRequest) request);
        chain.doFilter(parmsRequest, response);
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void destroy() {
    }
}

2.2 实现ParameterRequestWrapper

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import com.alibaba.fastjson.JSON;
/**
 * @author :
 * @description
 * @date : 2021/4/22
 */
public class ParameterRequestWrapper extends HttpServletRequestWrapper {
    private Map<String , String[]> params = new HashMap<>();
    public ParameterRequestWrapper(HttpServletRequest request) {
        super(request);
        Map<String, String[]> requestMap=request.getParameterMap();
        this.params.putAll(requestMap);
        this.modifyParameterValues();
    }
    @Override
    public ServletInputStream getInputStream() throws IOException {
        if(!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)){
            return super.getInputStream();
        }
        String json = IOUtils.toString(super.getInputStream(), "utf-8");
        if (StringUtils.isEmpty(json)) {
            return super.getInputStream();
        }
        Map<String,Object> map= jsonStringToMap(json);
        ByteArrayInputStream bis = new ByteArrayInputStream(JSON.toJSONString(map).getBytes("utf-8"));
        return new MyServletInputStream(bis);
    }
    public void modifyParameterValues(){
        Set<String> set = params.keySet();
        Iterator<String> it = set.iterator();
        while(it.hasNext()){
            String key= it.next();
            String[] values = params.get(key);
            values[0] = values[0].trim();
            params.put(key, values);
        }
    }
    @Override
    public String getParameter(String name) {
        String[]values = params.get(name);
        if(values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }
    @Override
    public String[] getParameterValues(String name) {
        return params.get(name);
    }
    class MyServletInputStream extends ServletInputStream {
        private ByteArrayInputStream bis;
        public MyServletInputStream(ByteArrayInputStream bis){
            this.bis=bis;
        }
        @Override
        public boolean isFinished() {
            return true;
        }
        @Override
        public boolean isReady() {
            return true;
        }
        @Override
        public void setReadListener(ReadListener listener) {
        }
        @Override
        public int read(){
            return bis.read();
        }
    }
    public static Map<String, Object> jsonStringToMap(String jsonString) {
        Map<String, Object> map = new HashMap<>();
        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        for (Object k : jsonObject.keySet()) {
            Object o = jsonObject.get(k);
            if (o instanceof JSONArray) {
                List<Map<String, Object>> list = new ArrayList<>();
                Iterator<Object> it = ((JSONArray) o).iterator();
                while (it.hasNext()) {
                    Object obj = it.next();
                    list.add(jsonStringToMap(obj.toString()));
                }
                map.put(k.toString(), list);
            } else if (o instanceof JSONObject) {
                map.put(k.toString(), jsonStringToMap(o.toString()));
            } else {
                if (o instanceof String) {
                    map.put(k.toString(), o.toString().trim());
                } else {
                    map.put(k.toString(), o);
                }
            }
        }
        return map;
    }
}

三、 完美解决

参数前后空格完美去除!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • springboot2.x使用Jsoup防XSS攻击的实现

    后端应用经常接收各种信息参数,例如评论,回复等文本内容.除了一些场景下面,可以特定接受的富文本标签和属性之外(如:b,ul,li,h1, h2, h3...),需要过滤掉危险的字符和标签,防止xss攻击. 一.什么是XSS? 看完这个,应该有一个大致的概念. XSS攻击常识及常见的XSS攻击脚本汇总 XSS过滤速查表 二.准则 永远不要相信用户的输入和请求的参数(包括文字.上传等一切内容) 参考第1条 三.实现做法 结合具体业务场景,对相应内容进行过滤,这里使用Jsoup. jsoup是一款Ja

  • java过滤特殊字符操作(xss攻击解决方案)

    XSS ,全名:cross-site scripting(跨站点脚本),是当前 web 应用中最危险和最普遍的漏洞之一.攻击者尝试注入恶意脚本代码(常js脚本)到受信任的网站上执行恶意操作,用户使用浏览器浏览含有恶意脚本页面时,会执行该段恶意脚本,进而影响用户(比如关不完的网站.盗取用户的 cookie 信息从而伪装成用户去操作)等等. 它与 SQL 注入很类似,同样是通过注入恶意指令来进行攻击.但 SQL 注入是在服务器端上执行的,而 XSS 攻击是在客户端上执行的,这点是他们本质区别. 其实

  • SpringBoot如何防止XSS注入攻击详解

    什么是 XSS 攻击 在跨站脚本(XSS)攻击中,攻击者可以在受害者的浏览器中执行恶意脚本.这种攻击通常是通过在网页中插入恶意代码 (JavaScript) 来完成的.攻击者在使用攻击后一般能够: 修改网页内容 将用户重定向到其他网站 访问用户的 Cookie 并利用此信息来冒充用户 访问有关用户系统的关键信息,例如地理位置,网络摄像头,文件系统 将木马功能注入应用程序 如果被攻击的用户在应用程序中具有更高的权限.攻击者可以完全控制应用程序,并破坏所有用户及其数据. XSS 攻击类型 常见的 X

  • springboot项目如何防止XSS攻击

    目录 1. 什么是XSS攻击? 2. 如何防范? 2.1 什么时候注入请求参数 3. 具体处理细节 1. 什么是XSS攻击? XSS攻击全称跨站脚本攻击,是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中.也就是作恶的用户通过表单提交一些前端代码,如果不做处理的话,这些前端代码将会在展示的时候被浏览器执行. 2. 如何防范? 有两种方式,一种是一些特殊字符转义,另一种是去除一些危险html元素.本文通过JSOUP库实现第二种方式. 现在问题是,在什么

  • springboot清除字符串前后空格与防xss攻击方法

    目录 springboot清除字符串前后空格与防xss攻击 一.查看WebMvcAutoConfiguration.class中的方法源码 二.自定义属性编辑器 三.创建WebBindingInitializerConfiguration类 springboot去除参数中前后空格说明 一. 需求 二. 解决方法 三. 完美解决 springboot清除字符串前后空格与防xss攻击 一.查看WebMvcAutoConfiguration.class中的方法源码 protected Configur

  • C#清除字符串内空格的方法

    本文实例讲述了C#清除字符串内空格的方法,分享给大家供大家参考.具体如下: 关键代码如下: 复制代码 代码如下: /// <summary> /// 清除字符串内空格 /// </summary> /// <param name="str">需要处理的字符串</param> /// <returns>处理好后的字符串</returns> public static string ExceptBlanks(this

  • python清除字符串中间空格的实例讲解

    1.使用字符串函数replace >>> a = 'hello world' >>> a.replace(' ', '') 'helloworld' 看上这种方法真的是很笨. 2.使用字符串函数split >>> a = ''.join(a.split()) >>> print(a) helloworld 3.使用正则表达式 >>> import re >>> strinfo = re.compil

  • python清除字符串前后空格函数的方法

    python有时候需要清除字符串前后空格,而字符本身的空格不需要清除掉,那就不能用正则re.sub来实现. 这时用到strip()函数 用法: str = ' 2014-04-21 14:10:18 ' str2 = str.strip() str3 = re.sub(' ','',str) print str2 print str3 结果如下: >2014-04-21 14:10:18 >2014-04-2114:10:18 以上这篇python清除字符串前后空格函数的方法就是小编分享给大家

  • JS 清除字符串数组中,重复元素的实现方法

    JS 清除字符串数组中,重复元素的实现方法 <script language="JavaScript"> <!-- var arrData=new Array(); for(var i=0; i<1000; i++) { arrData[arrData.length] = String.fromCharCode(Math.floor(Math.random()*26)+97); } //document.write(arrData+"<br/&g

  • SpringBoot+Redis+Lua防止IP重复防刷攻击的方法

    黑客或者一些恶意的用户为了攻击你的网站或者APP.通过肉机并发或者死循环请求你的接口.从而导致系统出现宕机. 针对新增数据的接口,会出现大量的重复数据,甚至垃圾数据会将你的数据库和CPU或者内存磁盘耗尽,直到数据库撑爆为止. 针对查询的接口.黑客一般是重点攻击慢查询,比如一个SQL是2S.只要黑客一致攻击,就必然造成系统被拖垮,数据库查询全都被阻塞,连接一直得不到释放造成数据库无法访问. 具体要实现和达到的效果是: 需求:在10秒内,同一IP 127.0.0.1 地址只允许访问30次. 最终达到

  • php通过session防url攻击方法

    本文实例讲述了php通过session防url攻击方法.分享给大家供大家参考.具体实现方法如下: 通过session跟踪,可以很方便地避免url攻击的发生,php采用session防url攻击方法代码如下: 复制代码 代码如下: <?php session_start();  $clean = array();  $email_pattern = '/^[^@s<&>]+@([-a-z0-9]+.)+[a-z]{2,}$/i';  if (preg_match($email_pa

  • xss防御之php利用httponly防xss攻击

    xss的概念就不用多说了,它的危害是极大的,这就意味着一旦你的网站出现xss漏洞,就可以执行任意的js代码,最可怕的是攻击者利用js获取cookie或者session劫持,如果这里面包含了大量敏感信息(身份信息,管理员信息)等,那完了... 如下js获取cookie信息: 复制代码 代码如下: url=document.top.location.href;cookie=document.cookie;c=new Image();c.src='http://www.test.com/c.php?c

  • JS去掉字符串前后空格或去掉所有空格的用法

    1.  去掉字符串前后所有空格: 代码如下: function Trim(str) { return str.replace(/(^\s*)|(\s*$)/g, ""); } 说明: 如果使用jQuery直接使用$.trim(str)方法即可,str表示要去掉前后所有空格的字符串.  2. 去掉字符串中所有空格(包括中间空格,需要设置第2个参数为:g) 代码如下: function Trim(str,is_global) { var result; result = str.repla

随机推荐