You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Bean Validation正则表达式规避CSV注入失效问题咨询

解决Bean Validation中限制CSV注入风险的输入校验问题

我之前在处理Java应用导出Excel的CSV注入风险时,也踩过正则在Bean Validation里不生效的坑,给你分享几个可行的解决办法:

一、修正正则表达式并正确配置Bean Validation

你之前用的两个正则没达到预期效果,主要是因为Bean Validation的@Pattern注解默认要求整个输入字符串完全匹配正则,而你的正则写法没覆盖所有场景:

问题分析

  • ^[^+=@-]:这个正则只匹配单个字符不属于=、+、-、@,但如果输入是多字符(比如abc),整个字符串不会被匹配,导致误判为非法输入。
  • ^((?![+=@-]).)*:这个负前瞻的写法逻辑是对的,但可能没考虑开头的空白字符,或者缺少匹配空字符串的场景(如果允许空输入的话)。

正确的正则写法

根据你的需求,要禁止输入以=、+、-、@开头(包括开头有空白字符的情况),可以用这个正则:

^(?!\\s*[+=@-]).*

如果不允许空输入,改成:

^(?!\\s*[+=@-]).+

在Bean Validation中使用

直接在字段上配置@Pattern:

import jakarta.validation.constraints.Pattern;

public class ExportForm {
    @Pattern(
        regexp = "^(?!\\s*[+=@-]).*",
        message = "输入内容不能以=、+、-、@开头(包括开头带空格的情况)"
    )
    private String userInput;

    // getter、setter
}

二、自定义Validator(更直观易调试)

如果正则表达式总是容易踩坑,推荐自定义一个专门的校验注解,逻辑更清晰,也方便后续扩展:

1. 定义校验注解

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = NoCsvInjectionValidator.class)
public @interface NoCsvInjection {
    String message() default "输入内容不能以=、+、-、@开头";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

2. 实现校验逻辑

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.Set;

public class NoCsvInjectionValidator implements ConstraintValidator<NoCsvInjection, String> {
    // 定义禁止作为开头的字符集合
    private static final Set<Character> INVALID_START_CHARS = Set.of('=', '+', '-', '@');

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 空值可以根据业务需求返回true或false
        if (value == null || value.trim().isEmpty()) {
            return true;
        }
        // 先去除开头空白,再判断第一个字符
        String trimmedValue = value.trim();
        char firstChar = trimmedValue.charAt(0);
        return !INVALID_START_CHARS.contains(firstChar);
    }
}

3. 在字段上使用

public class ExportForm {
    @NoCsvInjection
    private String userInput;

    // getter、setter
}

这个方案的好处是逻辑一目了然,比如后续要新增禁止的开头字符,直接修改集合即可,不需要调整正则表达式。

内容的提问来源于stack exchange,提问作者Rajinder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:46:56