JSR -303 BEAN验证 - 避免绕过字段



假设我们有这个bean

public class Bean {
   @NotBlank(groups = {CheckForEmployee.class, CheckForAdmins.class})
   private String sth1;
   @NotBlank(groups = {CheckForAdmins.class})
   private String sth2;
   //getters and setters
}

现在在员工UI中,我们有类似的东西:

<input name="sth1" type="text" />

这是针对管理员:

<input name="sth1" type="text" />
<input name="sth2" type="text" />

我们都知道像Spring这样的框架可以将这些值绑定到Bean对象,例如在春季,我们有类似的东西:

public ModelAndView method1 (@Validated({CheckForEmployee.class})@ModelAttribute Bean bean){...} 
//For Employee
AND
public ModelAndView method2 (@Validated({CheckForAdmin.class})@ModelAttribute Bean bean){...} 
//For Admin

现在是一个问题:如果A 恶意员工请注意,对于管理员来说,有一个名为" sth2" 的字段,他可以生成邮政请求手动,并放置值对于 sth2 ,并将其发送到服务器。

弹簧将结合此值,因为:

  1. 该字段在Bean类内部
  2. sTH2没有验证员工

您的解决方案是什么?

假设CSRF是禁用的,我们仍然想使用Spring Binding

public class Bean {
    @NotBlank(groups = Validator.CheckForEmployee.class)
    private String sth1;

    @BlockAccess(groups = Validator.CheckForEmployee.class)
    @NotBlank(groups = Validator.CheckForAdmin.class)
    private String sth2;
    //getters and setters
}
public class Validator {
    public interface CheckForEmployee{}
    public interface CheckForAdmin{}
}

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = BlockAccessImpl.class)
@Documented
public @interface BlockAccess {
    String message() default "Access is denied!";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
public class BlockAccessImpl implements ConstraintValidator<BlockAccess, Object> {
    @Override
    public void initialize(BlockAccess constraintAnnotation) {
    }
    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        return false;
    }
}
public class Test {
    public static void main(String[] args) {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        Bean b = new Bean();
        b.setSth1("Hi");
        b.setSth2("Bye");
        Set<ConstraintViolation<Bean>> s = validator.validate(b, Validator.CheckForEmployee.class);
        for (ConstraintViolation<Bean> f : s) {
            System.out.println(f.getPropertyPath() + " " + f.getMessage());
        }
    }
}

sth2访问被拒绝!

最新更新