java中SpringMVC中@PathVariable注解的XSS注入问题
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 "";
}
}
</td></tr></table>其中url的path并不走HttpServletRequest,同样也存在XSS问题。
用SpingMVC时觉得应该有一个解析UrlPath的类来完成这个工作(就像HandlerMapping、ViewResovler一样),让用户自定义,但实际上并没有。分析源码url匹配解析是在AbstractHandlerMapping这个类中。
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy3722')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy3722>/* 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<String, String> decodePathVariables(HttpServletRequest request, Map<String, String> vars){
Map<String, String> 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<String, String> decodeMatrixVariables(HttpServletRequest request,
MultiValueMap<String, String> vars){
MultiValueMap<String, String> mvm = super.decodeMatrixVariables(request, vars);
if(!CollectionUtils.isEmpty(mvm)){
for(String key : mvm.keySet()){
List<String> 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);
}
}
}
</td></tr></table>监听bean的实例化,然后即可设置所有HandlerMapping的UrlPathHelper。当然如果使用的Spring的4.x版本,已经提供了自定义UrlPathHelper配置了:
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy8675')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy8675><mvc:annotation-driven enable-matrix-variables="false" >
<mvc:path-matching path-helper="" path-matcher="" />
</mvc:annotation-driven>
这样基本已在输入源头解决的XSS问题。如果站点还存在js跨域等其它问题,也可引入Content-Security-Policy。
您可能感兴趣的文章:
java中SpringMVC中@PathVariable注解的XSS注入问题
php防止SQL注入攻击与XSS攻击的方法
PHP的防御XSS注入的终极解决方案
php程序员可以转java吗?
php安全问题思考
php防范SQL注入攻击与XSS攻击的方法详解
php csrf攻击与xss攻击区别
PHP常见安全问题及解决方法
解决SpringMVC使用FastJsonHttpMessageConverter时Swagger2失效的办法
php 过滤存储型XSS攻击