基于Validate排序字段防SQL注入

编程

一、定义排序基类

public interface BaseSortModel {

String getSort();

@ApiModelProperty(hidden = true)

default String getSortField() {

if (StringUtils.isNotBlank(getSort()) && getSort().contains("-")) {

return getSort().split("-")[0];

}

return null;

}

@ApiModelProperty(hidden = true)

default String getSortType() {

if (StringUtils.isNotBlank(getSort()) && getSort().contains("-")) {

return getSort().split("-")[1];

}

return null;

}

}

二、定义校验注解

@Target({ FIELD,   PARAMETER})

@Retention(RUNTIME)

@Documented

@Constraint(validatedBy = {Sort.SortValidator.class})

public @interface Sort {

String message() default "不支持的排序字段";

Class<?>[] FieldOfClass() default {};

String[] fields() default {};

Class<?>[] groups() default {};

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

}

三、定义校验器

@Slf4j

class SortValidator implements ConstraintValidator<Sort, String> {

private static Map<String, Set<String>> supportBeanFields = Maps.newConcurrentMap();

private static List<String> supportSortTypes = Lists.newArrayList("asc", "ASC", "desc", "DESC");

private Sort sortAnn;

@Override

public void initialize(Sort ann) {

this.sortAnn = ann;

if (ArrayUtils.isNotEmpty(sortAnn.FieldOfClass())) {

for (Class<?> clz : sortAnn.FieldOfClass()) {

Set<String> clzFields = supportBeanFields.get(clz.getName());

if (Objects.nonNull(clzFields)) {

continue;

}

Field[] fields = clz.getDeclaredFields();

if (ArrayUtils.isEmpty(fields)) {

supportBeanFields.putIfAbsent(clz.getName(), Sets.newHashSet());

continue;

}

clzFields = Sets.newHashSetWithExpectedSize(fields.length * 2);

for (Field field : fields) {

field.setAccessible(true);

clzFields.add(field.getName());

clzFields.add(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName()));

}

supportBeanFields.putIfAbsent(clz.getName(), clzFields);

}

}

}

/**

* 校验排序字段

*

* @param value 值

* @param context 校验器上下文

* @return 是否校验成功

*/

@Override

public boolean isValid(String value, ConstraintValidatorContext context) {

if (StringUtils.isEmpty(value)) {

return true;

}

if (!SQLFilter.checkSqlInject(value)) {

return false;

}

String[] split = value.split("-");

if (split.length != 2) {

log.error("排序字段格式格式有误,比如[字段名-asc]");

return false;

}

String sortField = split[0];

String sortType = split[1];

if (ArrayUtils.isEmpty(sortAnn.fields()) && ArrayUtils.isEmpty(sortAnn.FieldOfClass())) {

log.error("排序字段必须限定枚举值,请对@sort的fields或者fieldOfClass赋值)");

return false;

}

boolean isSupport = false;

if (ArrayUtils.isNotEmpty(sortAnn.fields())) {

if (ArrayUtils.contains(sortAnn.fields(), sortField)) {

isSupport = true;

}

}

if (ArrayUtils.isNotEmpty(sortAnn.FieldOfClass())) {

for (Class<?> clz : sortAnn.FieldOfClass()) {

Set<String> supportFields = supportBeanFields.get(clz.getName());

if (supportFields.contains(sortField)) {

isSupport = true;

break;

}

}

}

if (!supportSortTypes.contains(sortType)) {

log.error("不支持的排序类型, 仅支持[asc、desc]");

return false;

}

return isSupport;

}

}

四、SQL注入校验工具类

@Slf4j

public class SQLFilter {

public static String[] illegalKeywords = {""", """, ";", "\", "master", "truncate", "insert", "select", "delete", "update", "declare", "alert", "drop"};

/**

* SQL注入校验

*

* @param param 待验证的字符串

*/

public static String sqlInject(String param){

if(StringUtils.isBlank(param)){

return param;

}

String lowerParam = param.toLowerCase();

for(String illegalKeyword : illegalKeywords){

if(lowerParam.contains(illegalKeyword)){

throw new ParameterException(ReturnCode.PARAM_ERROR,

"参数:[" + param + "],含非法关键词[", ", ;, \, master, truncate, insert, select, delete, update, declare, alert, drop]");

}

}

return param;

}

/**

* SQL注入校验

*

* @param param 待验证的字符串

*/

public static boolean checkSqlInject(String param){

if(StringUtils.isBlank(param)){

return true;

}

String lowerParam = param.toLowerCase();

for(String illegalKeyword : illegalKeywords){

if(lowerParam.contains(illegalKeyword)){

return false;

}

}

return true;

}

}

以上是 基于Validate排序字段防SQL注入 的全部内容, 来源链接: utcz.com/z/517241.html

回到顶部