Java解决xss转义导致转码的问题

 更新时间:2023年08月31日 10:54:58   作者:熟透的蜗牛  
跨站脚本攻击XSS是最普遍的Web应用安全漏洞,本文主要介绍了Java解决xss转义导致转码的问题,具有一定的参考价值,感兴趣的可以了解一下

一、xss简介

人们经常将跨站脚本攻击(Cross Site Scripting)缩写为CSS,但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆。因此,有人将跨站脚本攻击缩写为XSS。跨站脚本攻击(XSS),是最普遍的Web应用安全漏洞。这类漏洞能够使得攻击者嵌入恶意脚本代码到正常用户会访问到的页面中,当正常用户访问该页面时,则可导致嵌入的恶意脚本代码的执行,从而达到恶意攻击用户的目的。

攻击者可以使用户在浏览器中执行其预定义的恶意脚本,其导致的危害可想而知,如劫持用户会话,插入恶意内容、重定向用户、使用恶意软件劫持用户浏览器、繁殖XSS蠕虫,甚至破坏网站、修改路由器配置信息等。

二、解决方式

解决方式有很多,这里介绍将内容经过转义然后再存储到服务器上。

package com.wssnail.xss.config;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.io.IOException;
import java.util.List;
import java.util.ListIterator;
/**
 * @author 熟透的蜗牛
 * @version 1.0
 * @description: 配置xss攻击过滤
 * @date 2023/8/14 23:48
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
        /**
         * 替换默认的MappingJackson2HttpMessageConverter,过滤(json请求参数)xss
         */
        ListIterator<HttpMessageConverter<?>> listIterator = messageConverters.listIterator();
        while (listIterator.hasNext()) {
            HttpMessageConverter<?> next = listIterator.next();
            if (next instanceof MappingJackson2HttpMessageConverter) {
                listIterator.remove();
                break;
            }
        }
        messageConverters.add(getMappingJackson2HttpMessageConverter());
    }
    public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
        // 创建自定义ObjectMapper
        SimpleModule module = new SimpleModule();
        module.addDeserializer(String.class, new JsonHtmlXssDeserializer(String.class));
        ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().applicationContext(this.getApplicationContext()).build();
        objectMapper.registerModule(module);
        // 创建自定义消息转换器
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
        mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
        return mappingJackson2HttpMessageConverter;
    }
    /**
     * 添加默认请求类型
     */
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.ignoreAcceptHeader(true).
                defaultContentType(MediaType.APPLICATION_JSON, MediaType.TEXT_XML, MediaType.APPLICATION_XML);
    }
}
/**
 * @author 熟透的蜗牛
 * @version 1.0
 * @description: 对xss进行过滤
 * @date 2023/8/14 23:49
 */
class JsonHtmlXssDeserializer extends JsonDeserializer<String> {
    public JsonHtmlXssDeserializer(Class<String> string) {
        super();
    }
    @Override
    public Class<String> handledType() {
        return String.class;
    }
    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException {
        String value = jsonParser.getValueAsString();
        if (!StringUtils.isEmpty(value)) {
            return StringEscapeUtils.escapeHtml4(value);
        }
        return value;
    }
}

 请求如上接口,经过转义之后,存到数据库的内容就不再是我们传参的数据,而是经过转义的内容

 经过查询之后内容就回显成转义之后的内容了,如下图

 三、解决转义的内容

先说一下思路,自定义一个注解,作用在实体类或者字段上,当查询的时候,在数据返回之前,对数据进行反转义。下面直接上代码。

自定义注解

package com.wssnail.xss.annotation;
import java.lang.annotation.*;
@Target({ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StringEscapeCode {
}

工具类

package com.wssnail.xss.utils;
import com.wssnail.xss.annotation.StringEscapeCode;
import org.apache.commons.text.StringEscapeUtils;
import java.lang.reflect.Field;
/**
 * @author 熟透的蜗牛
 * @version 1.0
 * @description: 配置字符串格式文本处理工具
 * @date 2023/8/14 23:50
 */
public class StringEscapeCodeUtil {
    public static void stringEscape(Class<?> clazz, Object obj) throws IllegalAccessException {
        StringEscapeCode declaredAnnotation = clazz.getDeclaredAnnotation(StringEscapeCode.class);
        if (declaredAnnotation != null) {
            Field[] fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                if (fields[i].getGenericType().toString().endsWith("String")) {
                    //有注解,设置字段
                    fields[i].setAccessible(true);
                    String value = StringEscapeUtils.unescapeHtml4((String) fields[i].get(obj));
                    fields[i].set(obj, value);
                }
            }
        } else {
            Field[] fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                StringEscapeCode annotation = fields[i].getAnnotation(StringEscapeCode.class);
                if (fields[i].getGenericType().toString().endsWith("String")) {
                    if (annotation != null) {
                        //有注解,设置字段
                        fields[i].setAccessible(true);
                        String value = StringEscapeUtils.unescapeHtml4((String) fields[i].get(obj));
                        fields[i].set(obj, value);
                    }
                }
            }
        }
    }
}

实际使用

package com.wssnail.xss.annotation;
import java.lang.annotation.*;
/**
 * @author 熟透的蜗牛
 * @version 1.0
 * @description: 自定义注解
 * 使用方法  将该注解添加到类上,或者属性上,只有作用在、string类型的属性上,注解才会生效
 * @date 2023/8/15 0:13
 */
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StringEscapeCode {
}
 public User getById(Integer id) {
        try {
            User user = userMapper.findByID(id);
            Class<? extends User> clazz = user.getClass();
            StringEscapeCodeUtil.unStringEscape(clazz, user);
            return user;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

然后查询的时候,就会正常显示内容了。 

 完整代码  xss-demo: 解决xss转义乱码返回的问题

到此这篇关于Java解决xss转义导致转码的问题的文章就介绍到这了,更多相关Java xss转义内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入浅出分析Java 类和对象

    深入浅出分析Java 类和对象

    面向对象乃是Java语言的核心,是程序设计的思想。Java语言的面向对象技术包括了面向对象和面向过程的基本概念,面向对象的特征,Java语言的类,对象,修饰符,抽象类等一系列的知识点
    2022-03-03
  • 一篇文章带你了解Java Stream流

    一篇文章带你了解Java Stream流

    Stream流是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。这篇文章主要介绍了Java8新特性Stream流的相关资料,需要的朋友参考下吧
    2021-08-08
  • Spring IOC与DI核心深入理解

    Spring IOC与DI核心深入理解

    IOC也是Spring的核心之一了,之前学的时候是采用xml配置文件的方式去实现的,后来其中也多少穿插了几个注解,但是没有说完全采用注解实现。那么这篇文章就和大家分享一下,全部采用注解来实现IOC+DI
    2023-02-02
  • Mybatis-Plus进阶分页与乐观锁插件及通用枚举和多数据源详解

    Mybatis-Plus进阶分页与乐观锁插件及通用枚举和多数据源详解

    这篇文章主要介绍了Mybatis-Plus的分页插件与乐观锁插件还有通用枚举和多数据源的相关介绍,文中代码附有详细的注释,感兴趣的朋友来看看吧
    2022-03-03
  • Java调用setStroke()方法设置笔画属性的语法

    Java调用setStroke()方法设置笔画属性的语法

    这篇文章主要介绍了Java调用setStroke()方法设置笔画属性的语法,如何改变线条的粗细、虚实和定义线段端点的形状、风格等,需要的朋友可以参考下
    2017-09-09
  • jvm堆外内存排查图文举例详解

    jvm堆外内存排查图文举例详解

    Java应用程序通过直接方式从操作系统中申请的内存,叫堆外内存,这篇文章主要给大家介绍了关于jvm堆外内存排查的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign的方法

    SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign的方法

    这篇文章主要介绍了SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Eclipse代码格式化设置简单介绍

    Eclipse代码格式化设置简单介绍

    这篇文章主要介绍了Eclipse代码格式化设置简单介绍,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • springboot整合mybatisplus的方法详解

    springboot整合mybatisplus的方法详解

    这篇文章主要为大家详细介绍了springboot整合mybatisplus的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • Java运用SWT插件编写桌面记事本应用程序

    Java运用SWT插件编写桌面记事本应用程序

    这篇文章主要为大家介绍了一个Java项目实战,一步步教你实现记事本,步骤很详细,运用SWT插件手把手编写记事本,感兴趣的小伙伴们可以参考一下
    2016-01-01

最新评论