Skip to content

引言

XSS(跨站脚本攻击,Cross-Site Scripting)是一种常见的安全漏洞,攻击者通过在网页中注入恶意脚本,窃取用户数据或执行未经授权的操作。为了防止 XSS 攻击。

输入过滤:对用户输入的数据进行转义或过滤,防止恶意脚本注入。
输出编码:在渲染页面时,对动态内容进行编码,防止浏览器执行恶意脚本。
内容安全策略(CSP):通过 HTTP 头设置 CSP,限制页面中可以加载的资源。

AOP优势

在项目中使用 AOP(面向切面编程)注解实现防重复提交具有以下优势:

1. 代码解耦:将日志记录逻辑与业务逻辑分离,避免代码重复,提升代码可读性和可维护性。
2. 灵活性与扩展性:通过注解可以灵活地控制哪些方法需要记录日志,便于扩展和修改日志记录逻辑。
3. 非侵入性:无需修改现有业务代码,只需在方法上添加注解即可实现日志记录。
4. 集中管理:日志记录逻辑集中在切面中,便于统一管理和维护。
5. 提高开发效率:通过注解方式快速实现日志功能,减少重复代码编写。

定义注解

xiaomayi-common/xiaomayi-xss 模块中定义的防重复提交的 AOP 切面 Xss 文件,内容如下:

js
package com.xiaomayi.xss.annotation;

import com.xiaomayi.xss.validator.XssValidator;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * <p>
 * 自定义Xss注解
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2024-06-11
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Constraint(validatedBy = {XssValidator.class})
public @interface Xss {

    /**
     * 提示语
     *
     * @return 返回结果
     */
    String message() default "不允许任何脚本运行";

    /**
     * 分组
     *
     * @return 返回结果
     */
    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}

防XSS攻击

js
package com.xiaomayi.xss.validator;

import com.xiaomayi.core.utils.StringUtils;
import com.xiaomayi.xss.annotation.Xss;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 自定义Xss注解验证实现
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2024-06-11
 */
public class XssValidator implements ConstraintValidator<Xss, String> {

    /**
     * 自定义过滤HTML标签正则表达式
     */
    private static final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />";

    /**
     * 是否通过验证
     *
     * @param s                          参数
     * @param constraintValidatorContext 验证内筒
     * @return 返回结果
     */
    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        // 参数判空
        if (StringUtils.isBlank(s)) {
            return true;
        }
        // 判断是否包含HTML标签
        return !containsHtml(s);
    }

    /**
     * 自定义是否包含HTML标签方法
     *
     * @param content 文本内容
     * @return 返回结果
     */
    public static boolean containsHtml(String content) {
        StringBuilder sHtml = new StringBuilder();
        Pattern pattern = Pattern.compile(HTML_PATTERN);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            sHtml.append(matcher.group());
        }
        return pattern.matcher(sHtml).matches();
    }

}

添加依赖

pom.xml 配置文件中引入以下依赖:

js
<!-- XSS依赖模块 -->
<dependency>
    <groupId>com.xiaomayi</groupId>
    <artifactId>xiaomayi-xss</artifactId>
</dependency>

注解使用

在需要防 XSS 攻击的字段上添加以下注解:

js
@Xss(message = "登录账号不能包含脚本字符")

使用案例:

js
package com.xiaomayi.system.dto.user;

import com.xiaomayi.xss.annotation.Xss;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
import lombok.Data;
import org.hibernate.validator.constraints.Range;

/**
 * <p>
 * 用户
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2024-03-23
 */
@Data
@Schema(name = "用户添加DTO", description = "用户添加DTO")
public class UserAddDTO {

    @Schema(description = "用户名称")
    @NotBlank(message = "用户名称不能为空")
    @Size(max = 150, message = "用户名称最多150个字符")
    private String realname;

    @Schema(description = "用户性别:1-男 2-女 3-保密")
    @NotNull(message = "用户性别不能为空")
    @Range(min = 1, max = 3, message = "用户性别值在1-3之间")
    private Integer gender;

    @Schema(description = "用户头像")
    @NotBlank(message = "用户头像不能为空")
    @Size(max = 255, message = "用户头像最多255个字符")
    private String avatar;

    @Schema(description = "手机号码")
    @NotBlank(message = "手机号码不能为空")
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
    private String mobile;

    @Schema(description = "邮箱地址")
    @NotBlank(message = "邮箱地址不能为空")
    @Email(message = "邮箱格式不正确")
    private String email;

    @Schema(description = "部门ID")
    @NotNull(message = "部门ID不能为空")
    @Min(value = 1, message = "部门ID必须大于0")
    private Integer deptId;

    @Schema(description = "职级ID")
    @NotNull(message = "职级ID不能为空")
    @Min(value = 1, message = "职级ID必须大于0")
    private Integer levelId;

    @Schema(description = "岗位ID")
    @NotNull(message = "岗位ID不能为空")
    @Min(value = 1, message = "岗位ID必须大于0")
    private Integer positionId;

    @Schema(description = "行政区划")
    @NotEmpty(message = "行政区划不能为空")
    private String[] city;

    @Schema(description = "详细地址")
    @NotBlank(message = "详细地址不能为空")
    @Size(max = 255, message = "详细地址最多255个字符")
    private String address;

    @Xss(message = "登录账号不能包含脚本字符")
    @Schema(description = "登录账号")
    @NotBlank(message = "登录账号不能为空")
    @Size(max = 50, message = "登录账号最多50个字符")
    private String username;

    @Xss(message = "登录密码不能包含脚本字符")
    @Schema(description = "登录密码")
    @NotBlank(message = "登录密码不能为空")
    private String password;

    @Schema(description = "加密盐")
    private String salt;

    @Schema(description = "个人简介")
    @Size(max = 500, message = "个人简介最多500个字符")
    private String intro;

    @Schema(description = "用户状态:1-正常 2-禁用")
    @NotNull(message = "用户状态不能为空")
    @Range(min = 1, max = 2, message = "用户状态值在1-2之间")
    private Integer status;

    @Schema(description = "用户备注")
    @Size(max = 500, message = "用户备注最多500个字符")
    private String note;

    @Schema(description = "用户排序")
    @NotNull(message = "用户排序不能为空")
    @Min(value = 0, message = "排序不得小于0")
    private Integer sort;

    @Schema(description = "用户角色ID集合")
    @NotEmpty(message = "用户角色ID集合不能为空")
    private Integer[] roles;

    @Schema(description = "租户ID,传值使用")
    private Integer tenantId;

}

测试验证

在添加用户时设置了登录账号、登录密码登字段的防 XSS 攻击案例,以下给账号输入一个特殊字符用于触发机制。

js
{
    "code": 1,
    "msg": "登录账号不能包含脚本字符",
    "data": null,
    "ok": false
}

使用 ApiFox 调试工具测试结果如下图:

总结

通过以上方案,可以有效防止 XSS 攻击,提升应用的安全性。

小蚂蚁云团队 · 提供技术支持

小蚂蚁云 新品首发
新品首发,限时特惠,抢购从速! 全场95折
赋能开发者,助理企业发展,提供全方位数据中台解决方案。
获取官方授权