Skip to content

Latest commit

 

History

History
73 lines (55 loc) · 3.15 KB

index.md

File metadata and controls

73 lines (55 loc) · 3.15 KB

Shiro-682

影响shiro<1.5.0,具体描述可以看官方https://issues.apache.org/jira/browse/SHIRO-682

在 SpingWeb 中处理 requestURI 与 shiro 中匹配鉴权路径差异导致的绕过问题:在 Spring 中,/resource/menus/resource/menus/ 都可以访问资源

@RequestMapping("/unauthorize")
@ResponseBody
public String UnAuthorize(){
  return "Bypassed";
}

spring 在分发请求时org.springframework.web.servlet.DispatcherServlet#doDispatch,会根据我们请求的URI选择一个最合适的handler,其实就是从 DispatcherServlet#handlerMappings 找到能匹配路径的 Handler

如图

而spring当中useTrailingSlashMatch默认为true,因此最终在org.springframework.web.servlet.mvc.condition.PatternsRequestCondition#getMatchingPattern当中,在前面没有命中时可仍然可以匹配到看else分支即可

if (this.pathMatcher.match(pattern, lookupPath)) {
    return pattern;
} else {
    return this.useTrailingSlashMatch && !pattern.endsWith("/") && this.pathMatcher.match(pattern + "/", lookupPath) ? pattern + "/" : null;
}

调用栈

getMatchingPatterns:236, PatternsRequestCondition (org.springframework.web.servlet.mvc.condition)
getMatchingCondition:221, PatternsRequestCondition (org.springframework.web.servlet.mvc.condition)
getMatchingCondition:240, RequestMappingInfo (org.springframework.web.servlet.mvc.method)
getMatchingMapping:94, RequestMappingInfoHandlerMapping (org.springframework.web.servlet.mvc.method)
getMatchingMapping:58, RequestMappingInfoHandlerMapping (org.springframework.web.servlet.mvc.method)
addMatchingMappings:427, AbstractHandlerMethodMapping (org.springframework.web.servlet.handler)
lookupHandlerMethod:393, AbstractHandlerMethodMapping (org.springframework.web.servlet.handler)
getHandlerInternal:367, AbstractHandlerMethodMapping (org.springframework.web.servlet.handler)
getHandlerInternal:449, RequestMappingHandlerMapping (org.springframework.web.servlet.mvc.method.annotation)
getHandlerInternal:67, RequestMappingHandlerMapping (org.springframework.web.servlet.mvc.method.annotation)
getHandler:393, AbstractHandlerMapping (org.springframework.web.servlet.handler)
getHandler:1234, DispatcherServlet (org.springframework.web.servlet)
doDispatch:1016, DispatcherServlet (org.springframework.web.servlet)

因此既然知道了这个那为什么能绕过就很明显了很明显我们访问的/unauthorize/和被限制的/unauthorize不同

@Bean(name = "shiroFilterFactoryBean")
public ShiroFilterFactoryBean ShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
  ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
  filter.setSecurityManager(defaultWebSecurityManager);


  Map<String,String> filterMap = new HashMap<>();
  filterMap.put("/unauthorize","authc");
  filterMap.put("/**", "anon");

  filter.setFilterChainDefinitionMap(filterMap);

  filter.setLoginUrl("/adminLogin");
  filter.setUnauthorizedUrl("/adminLogin");

  return filter;
}

看高版本的修复也很简单https://github.com/apache/shiro/pull/127/files

专门针对这种情况做了去处最后一个分隔符的处理