Solon v2.7.6

XSS 的处理机制参考

</> markdown

1、基于路由拦截机制的处理参考(或者用过滤器)

具体参考一个用户的代码:

@Slf4j
@Component
public class XssRouterInterceptor implements RouterInterceptor {

    @Override
    public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
        if (mainHandler != null) {
            //请求头
            for (Map.Entry<String, String> kv : ctx.headerMap().entrySet()) {
                //处理Val
                kv.setValue(cleanXss(kv.getValue()));
            }

            //请求参数
            for (Map.Entry<String, String> kv : ctx.paramMap().entrySet()) {
                //处理val
                kv.setValue(cleanXss(kv.getValue()));
            }
            
            //请求主体
            if (ctx.contentType() != null && ctx.contentType().contains("json")) {
                //处理vaL
                ctx.bodyNew(cleanXss(ctx.body();));
            }
        }
        
        chain.doIntercept(ctx, mainHandler);
    }

    private String cleanXss(String input) {
        if(StrUtil.isBlankOrUndefined(input)){
            return input;
        }

        input = XssUtil.removeEvent(input);
        input = XssUtil.removeScript(input);
        input = XssUtil.removeEval(input);
        input = XssUtil.swapJavascript(input);
        input = XssUtil.swapVbscript(input);
        input = XssUtil.swapLivescript(input);
        input = XssUtil.encode(input);

        return input;
    }
}

2、基于验证机制的处理参考

以下代码,也自交流群的用户。

  • 定义 @Xss 验证注解
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Xss {
    String message() default "";
}
  • 定义验证器并注册
//定义验证器
public class XssValidator implements Validator<Xss> {
    @Override
    public String message(Xss anno) {
        return anno.message();
    }
    
    @Override
    public Result validateOfValue(Xss anno, Object val, StringBuilder tmp) {
        return verifyDo(anno, String.valueOf(val));
    }
    
    @Override
    public Result validateOfContext(Context ctx, Xss anno, String name, StringBuilder tmp) {
        String val = ctx.param(name);
        return verifyDo(anno, val);
    }
    
    private Result verifyDo(Xss anno, String val) {
        if (Utils.isBlank(val)) {
            return Result.succeed();
        }

        if (Pattern.compile("\"<(\\\\S*?)[^>]*>.*?|<.*? />\"").matcher(val).matches()) {
           return Result.failure();
        } else {
            return Result.succeed();
        }
    }
}

//注册验证器
@Configuration
public class XssConfig{
    @Bean
    public void xssInit(){
        ValidatorManager.register(Xss.class, new XssValidator());
    }
}
  • 代码应用
@Controller
public class DemoController{
    @Mapping("demo")
    public void demo(@Xss String name){
        //...
    }
}