一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

java中SpringMVC中@PathVariable注解的XSS注入问题

时间:2016-06-02 编辑:简简单单 来源:一聚教程网

 XSS注入算是一个很常见的问题,其实解决起来并不难,但是有很多需要注意的地方,这里做一个完整的解决方案。

   Java中常见的解决方案是继承HttpServletRequestWrapper,然后重载getParameter、getHeader等方法。但是要注意到文件上传是不走HttpServletRequestWrapper的,所有还需要解决文件上传时的xss问题。如果用SpringMVC,那么直接继承CommonsMultipartResolver即可。


如果使用了url中部分path(即@PathVariable注解)值,同样有xss问题。常见代码如下:

 代码如下 复制代码

@Controller
@RequestMapping("/some")
public class SomeController{
 
  @RequestMapping(value = "/{somepath}")
  public String func(@PathVariable("somepath")String somepath){
    doSomething(path);
    return "";
   }

}

其中url的path并不走HttpServletRequest,同样也存在XSS问题。

    用SpingMVC时觉得应该有一个解析UrlPath的类来完成这个工作(就像HandlerMapping、ViewResovler一样),让用户自定义,但实际上并没有。分析源码url匹配解析是在AbstractHandlerMapping这个类中。

 代码如下 复制代码

/* org.springframework.web.servlet.handler.AbstractHandlerMapping 类 */
public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport implements HandlerMapping, Ordered {
   private int order = Integer.MAX_VALUE;  // default: same as non-Ordered
   private Object defaultHandler;
   private UrlPathHelper urlPathHelper = new UrlPathHelper();
   private PathMatcher pathMatcher = new AntPathMatcher();

/* 省略代码... */

  其中UrlPathHelper 类中包含decodePathVariables和decodeMatrixVariables两个方法即为抽取path参数,所以自定义一个UrlPathHelper来完成参数过滤功能。然后所有AbstractHandlerMapping均使用自定义UrlPathHelper即可。但是需要注意的是SpringMVC默认产生了两个HandlerMapping->RequestMappingHandlerMapping和BeanNameUrlHandlerMapping,其是在WebMvcConfigurationSupport这个类中产生的,所有必须设置这两个HandlerMapping的urlPathHelper,没有直接的调用接口,那么监听Spring的bean实例化即可,创建类如下:

/* 解决@PathVariable注解造成的xss攻击问题,注意:此类必需由WebApplicationContext初始化 */
public class XssHandlerMappingPostProcessor implements BeanPostProcessor{

  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException{
    return bean;
  }

  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException{
    if(bean instanceof AbstractHandlerMapping){
      AbstractHandlerMapping ahm = (AbstractHandlerMapping) bean;
      ahm.setUrlPathHelper(new XssUrlPathHelper());
    }

    return bean;
  }

  static class XssUrlPathHelper extends UrlPathHelper{

    @Override
    public Map decodePathVariables(HttpServletRequest request, Map vars){
      Map result = super.decodePathVariables(request, vars);
      if(!CollectionUtils.isEmpty(result)){
        for(String key : result.keySet()){
          result.put(key, cleanXSS(result.get(key)));
        }
      }

      return result;
    }

    @Override
    public MultiValueMap decodeMatrixVariables(HttpServletRequest request,
        MultiValueMap vars){
      MultiValueMap mvm = super.decodeMatrixVariables(request, vars);
      if(!CollectionUtils.isEmpty(mvm)){
        for(String key : mvm.keySet()){
          List value = mvm.get(key);
          for(int i = 0; i < value.size(); i++){
            value.set(i, cleanXSS(value.get(i)));
          }
        }
      }

      return mvm;
    }

    private String cleanXSS(String value){
      return HtmlUtils.htmlEscape(value);
    }

  }

}

监听bean的实例化,然后即可设置所有HandlerMapping的UrlPathHelper。当然如果使用的Spring的4.x版本,已经提供了自定义UrlPathHelper配置了:

 代码如下 复制代码


 

这样基本已在输入源头解决的XSS问题。如果站点还存在js跨域等其它问题,也可引入Content-Security-Policy。

热门栏目