整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

SpringBoot如何防止XSS脚本攻击?

SpringBoot如何防止XSS脚本攻击?

么是XSS脚本攻击?

XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的 Web 攻击技术,攻击者通过在 Web 页面中插入恶意的脚本代码,使得用户在浏览页面时执行这些脚本,从而达到攻击的目的。通常被分为如下的三种类型。

存储型 XSS(Stored XSS)

攻击者将恶意脚本代码存储在服务器上的数据库或文件中,当用户访问包含这些恶意代码的页面时,会执行这些代码。

反射型 XSS(Reflected XSS)

攻击者将恶意脚本代码作为参数注入到URL中,当用户点击包含这些恶意参数的URL时,服务器端将参数反射回页面并执行,从而触发XSS攻击。

DOM 型 XSS(DOM-based XSS)

攻击者利用客户端脚本对DOM(Document Object Model,文档对象模型)进行操作的漏洞,通过修改页面的DOM结构来执行恶意代码。

常见的XSS攻击防御手段

  • 过滤和清理用户输入数据,移除或转义HTML标签和特殊字符
  • 使用 Content Security Policy(CSP)来限制页面资源加载和执行的范围。
  • 使用安全的编码函数来处理用户输入和输出,如HTML编码、URL编码等
  • 对于敏感操作和数据,使用HttpOnly标记和Secure标记来设置Cookie的属性,防止被窃取和劫持。
  • 对于存储型XSS,严格控制用户输入的内容,并对输入数据进行验证和过滤。
  • 对于反射型XSS,验证和过滤所有用户提交的数据,包括URL参数、表单数据等。
  • 对于DOM型XSS,避免直接使用用户输入的数据操作DOM,尽量使用安全的DOM操作方式。

如何实现?

SpringBoot可以通过使用过滤器或拦截器来对请求参数进行过滤和清理,防止恶意的XSS脚本注入。下面是一种通过过滤器实现防止XSS攻击的方法。

创建一个自定义的过滤器,用于过滤请求中的参数,并清理其中的HTML标签和特殊字符。

@WebFilter("/*")
public class XSSFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化操作,可以留空
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
    }
    @Override
    public void destroy() {
        // 销毁操作,可以留空
    }
    static class XSSRequestWrapper extends HttpServletRequestWrapper {
        XSSRequestWrapper(HttpServletRequest request) {
            super(request);
        }
        @Override
        public String getParameter(String name) {
            String value=super.getParameter(name);
            if (value !=null) {
                value=cleanXSS(value);
            }
            return value;
        }
        private String cleanXSS(String value) {
            // 进行 XSS 过滤,清理 HTML 标签和特殊字符
            // 例如,可以使用正则表达式或者第三方库进行过滤
            // 这里只是简单示例,具体过滤规则需根据实际情况自行设计
            return value.replaceAll("<", "<")
                        .replaceAll(">", ">")
                        .replaceAll("\"", """)
                        .replaceAll("'", "'")
                        .replaceAll("&", "&");
        }
    }
}

在SpringBoot应用的配置类中注册该过滤器。

@Bean
public FilterRegistrationBean<XSSFilter> xssFilterRegistration() {
    FilterRegistrationBean<XSSFilter> registration=new FilterRegistrationBean<>();
    registration.setFilter(new XSSFilter());
    registration.addUrlPatterns("/*");
    registration.setName("xssFilter");
    registration.setOrder(1);
    return registration;
}

上述代码,我们创建了一个名为XSSFilter的过滤器,在doFilter方法中,对请求进行过滤,并在需要时使用XSSRequestWrapper对请求参数进行清理。清理过程中,我们简单地将 HTML 标签和一些特殊字符替换为相应的转义序列,以防止恶意脚本注入。

请注意,这只是一种简单的示例,实际场景中应根据具体情况制定更为严格的过滤规则。

.Thymeleaf 介绍

1.1 Thymeleaf 简介

Thymeleaf是用于Web和独立环境的现代服务器端Java模板引擎。能够处理 HTML、XML、JavaScript、CSS 甚至纯文本。
Thymeleaf 的主要目标是提供一种优雅且高度可维护的模板创建方式。为了实现这一点,它建立在自然模板的概念之上,以不影响模板用作设计原型的方式将其逻辑注入模板文件。这改善了设计的沟通并弥合了设计和开发团队之间的差距。
Thymeleaf 的设计从一开始就考虑到了 Web 标准——尤其是 HTML5——允许您在需要时创建完全验证模板。

官网
https://www.thymeleaf.org/

官方文档
https://www.thymeleaf.org/documentation.html

1.2 Thymeleaf 特性

  • 动静结合:Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。
  • 开箱即用:它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、该jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。
  • 多方言支持:Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
  • 与SpringBoot完美整合,SpringBoot提供了Thymeleaf的默认配置,并且为Thymeleaf设置了视图解析器,我们可以像以前操作jsp一样来操作Thymeleaf。代码几乎没有任何区别,就是在模板语法上有区别。

1.3 Thymeleaf语法

1.3.1 表达式

- th::利用H5的自定义属性实现,需要支持H5,不支持时需要使用data-th:代替
- ${...}:变量表达式,类似el表达式,获取接口绑定的变量数据
- *{...}:选择变量表达式,通常情况下与变量表达式一致,但是当指定了变量后,可以使用选择表达式直接引用对象的属性名而不是通过对象.属性
- #{...}:消息表达式,用于展示消息内容,也可以引用变量内容,常用于国际化
- @{...}:链接表达式,设置超链接时使用,与th:href等标签配合
- ~{...}:片段表达式,将重复使用的内容提取出来引用

1.3.2 渲染标签

- th:id:替换标签的id属性值,
- th:value:替换标签的value属性值,该标签通常用于input标签中,为其value属性赋值
- th:href:替换标签的href属性值(a标签),<a th:href="@{index.html}">超链接</a>
- th:src:替换标签的src属性值(img等标签),<script type="text/javascript" th:src="@{index.js}"></script>
- th:text:设置当前元素的文本内容,相同功能的还有th:utext,两者的区别在于前者不会转义html标签,后者会。优先级不高:order=7。
- th:utext:支持使用html的文本替换当前标签内容
- th:object:替换标签中的对象
- th:each:遍历变量中的值,迭代对象可以是java.util.List,java.util.Map,数组等数据类型;
- th:if:条件语句,取值应为布尔类型,如果为false则当前标签内容不显示
- th:unless:条件语句,取值应为布尔类型,如果为true则当前标签内容不显示
- th:switch:条件语句,取值对应case内容,只显示对应case标签
- th:case:请求返回绑定user对象的集合数据,user对象包含name、age、gender等属性,此时模板页使用条件和遍历标签渲染数据有以下形式。

2.SpringBoot集成Thymeleaf

整体代码结构如下:

2.1 maven 依赖

在pom文件中引入freemarker,当然在SpringBoot中是通过引入SpringBoot已经提供好的starter。完整的pom依赖引入如下:

  <dependencies>
        <!-- thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

2.2 配置文件

spring:
  application:
    name: springboot-thymeleaf
  thymeleaf:
    # 是否启用模板缓存。
    cache: false
    # 是否检查模板位置是否存在。
    check-template: true
    # 是否为Web框架启用Thymeleaf视图分辨率。
    enabled: true
    # 编码格式, 默认UTF-8
    encoding: UTF-8
    # 应用于模板的模板模式。另请参阅Thymeleaf的TemplateMode枚举。
    mode: HTML
    # 后缀 默认 .html
    suffix: .html
    # 模板文件存放位置  , 默认 classpath:/templates/
    prefix: classpath:/templates/

2.3 演示业务代码

我们建一个用户实体

@Data
public class User {

    private String username;

    private Integer age;

    private String email;

    private String address;
}

创建Controller类并提供请求方法

@Controller
public class UserController {

    @GetMapping("/")
    public String getStudents(Model model) {
        List<User> list=new ArrayList<>();
        User userOne=new User();
        userOne.setUsername("小明");
        userOne.setAge(12);
        userOne.setEmail("xxx@qq.com");
        userOne.setAddress("安徽省合肥市");
        list.add(userOne);

        User userTwo=new User();
        userTwo.setUsername("小红");
        userTwo.setAge(13);
        userTwo.setEmail("xxx@126.com");
        userTwo.setAddress("安徽省合肥市");
        list.add(userTwo);

        model.addAttribute("users", list);
        return "users";
    }
}

users.html页面代码如下:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table border="1">
    <thead>
    <tr>
        <th>名称</th>
        <th>年龄</th>
        <th>邮件</th>
        <th>地址</th>
    </tr>
    </thead>
    <tbody>
    <!-- 遍历集合,如果被遍历的变量 users 为 null 或者不存在,则不会进行遍历,也不报错-->
    <tr th:each="user : ${users}">
        <td th:text="${user.username}"></td>
        <td th:text="${user.age}"></td>
        <td th:text="${user.email}"></td>
        <td th:text="${user.address}"></td>
    </tr>
    </tbody>
</table>
</body>
</html>

2.4 测试结果

启动项目,我们打开链接http://127.0.0.1:8080/

篇文章跟大家简单介绍了一下spring boot常用的集中模板引擎,因为对groovy和mustache模板引擎了解的比较少,所以这两个就没给大家介绍,本次就简单介绍一下这两个模板引擎如何在spirng boot中使用。

Groovy:在我的了解中,groovy是一种兼容java的开发语言,我目前开发的项目就是使用的Grails框架结合groovy语言。但是使用这个模板引擎还是第一次用。网上是这样说的:Groovy语言包含了一个模板引擎功能,可以生成各种类型的格式化文件,非常方便。模板引擎有下面几个,它们都实现了Template接口:

  • SimpleTemplateEngine - 基本的模板

  • StreamingTemplateEngine - 功能和 SimpleTemplateEngine相同,不过支持大于64k的模板

  • GStringTemplateEngine - 将模板保存为可写的闭包,在流式场景中很有用

  • XmlTemplateEngine - 输出XML文件的模板引擎

  • MarkupTemplateEngine - 一个完整的、优化过的模板引擎,可以用于生成HTML等模板

代码格式和方法

标记模板其实是合法的Groovy代码。

yieldUnescaped '<!DOCTYPE html>'

html(lang:'en') {

head {

meta('http-equiv':'"Content-Type" content="text/html; charset=utf-8"')

title('My page')

}

body {

p('This is an example of HTML contents')

}

}

常用的方法:

yieldUnescaped方法会直接输出给定的语句,不转义其中的字符。

yield方法和上面相反,会转义特殊字符。

head这些HTML标签方法会生成对应的标签。

xmlDeclaration()方法会生成一个标准的XML文档头。

comment方法生成HTML注释。

newLine生成一个新行。

如何在spring boot中使用这个模板引擎呢?

  1. pom中添加依赖

2.controller

3.新建indexg.tpl,groovy模板页面扩展名是tpl

和平常所见到的页面结构不太一样,想要学习这个技术的可以直接访问图片中的链接,查看官方文档学习。

4.运行结果

Mustache:mustache官方给出的是Logic-less templates.翻译过来就是逻辑很少的模板,Mustcache可以被用于html文件,配置文件,源代码等等很多场景,它的运行得益于扩展一些标签在模板文件中,然后使用一个hash字典或者对象对其进行替换渲染。我们之所以称之为“logic-less”是因为他摒弃了if else 以及for loop 这样的语句,取而代之的是只有标签,有些标签被替换成一个值,或者不作为,或者是一系列的值,比如数组或者一个列表,标签有几种不同的类型,自接下来我们会逐个介绍,但是你要相信他非常简单,因为他是“logic-less”的。(摘自wangwenjun69的csdn博客)

这个模板我也不是很了解,就简单介绍一下如何在spring boot中使用

  1. pom中引入依赖

2.controller

3.新建indexm.html

4.访问

至此,spring boot中推荐的5种模板引擎就介绍完了,都是最简单的应用,希望对入门的朋友有所帮助。