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
相关产品推荐
相关产品推荐

