在使用Apache Shiro进行权限控制时,部分开发者因配置不当或对过滤器链解析机制理解不深,导致出现权限绕过漏洞。常见问题之一是:**如何正确配置Shiro的Filter Chain以防止URL路径匹配不全或被恶意构造请求绕过鉴权?** 例如,攻击者通过添加特殊字符、多层编码或利用路径遍历等方式访问未被拦截的接口。该问题暴露出在实际部署中对`anon`、`authc`等过滤器应用范围把控不严的风险。需结合精确的URL匹配规则、合理的过滤器顺序及全局拦截策略,确保所有敏感接口均被有效保护。
1条回答 默认 最新
白萝卜道士 2025-10-22 08:38关注一、Apache Shiro Filter Chain 配置中的权限绕过问题剖析
在使用 Apache Shiro 进行权限控制时,Filter Chain 的配置是安全策略的核心。然而,许多开发者因对路径匹配机制理解不深或配置顺序不当,导致出现严重的权限绕过漏洞。
1.1 常见的权限绕过方式与攻击向量
- 通过添加分号(;)构造恶意路径,如
/admin;index.html - 利用双重编码绕过匹配规则,例如
%252F解码为%2F再解码为/ - 路径遍历攻击:
/../../../etc/passwd或/././admin - 利用未覆盖的 URL 后缀,如访问
/api/user.js而非/api/user - 通过添加查询参数或锚点干扰匹配逻辑
1.2 Shiro 路径匹配机制解析
Shiro 使用 Ant-style 路径匹配,默认由
PathMatchingFilterChainResolver处理。其匹配顺序遵循“最长路径优先”原则,但若配置不当,将导致短路径或模糊路径优先匹配,从而跳过更严格的规则。路径模式 匹配示例 风险场景 /api/** /api/user, /api/v1/log 可能遗漏对具体方法的控制 /admin/* /admin/login 无法匹配 /admin/settings/edit /**/*.jsp /secure/page.jsp 静态资源暴露风险 /;index /admin;index 分号绕过典型案例 1.3 典型错误配置示例
shiro.filterChainDefinitions = /login = anon /logout = logout /static/** = anon /** = authc上述配置看似完整,但存在隐患:若前端服务器(如 Nginx)未规范化请求路径,攻击者可通过
/admin/..%252fsecret绕过认证。1.4 正确的 Filter Chain 配置原则
- 精确路径优先于通配符路径
- 敏感接口必须显式声明
authc或更细粒度的权限过滤器 - 避免过度依赖
/** = authc作为兜底规则 - 对静态资源和公开接口明确标记为
anon - 使用前缀拦截而非后缀匹配防止扩展名绕过
- 启用路径规范化预处理
- 结合 Web 容器进行 URL 规范化(去除分号、解码等)
- 定期审计 Filter Chain 的覆盖范围
1.5 安全增强配置实践
shiro.filterChainDefinitions = # 公开资源 /login = anon /logout = logout /static/** = anon /favicon.ico = anon # 精确保护管理接口 /admin/login = anon /admin/** = authc, roles[admin] # API 接口强制认证 /api/v1/** = authc, perms["api:access"] # 特殊路径防御 /*.* = noSessionCreation, authc # 防止 .json/.js 等绕过 /;* = deny # 显式拒绝含分号路径 # 兜底策略 /** = authc1.6 深层防御机制设计
仅靠 Shiro 配置不足以抵御所有绕过手段。应构建多层防护体系:
graph TD A[客户端请求] --> B{Nginx/Apache} B --> C[URL规范化: 解码、去分号、路径压缩] C --> D[Shiro Filter Chain] D --> E{路径匹配引擎} E --> F[/login → anon] E --> G[/admin/** → authc + roles] E --> H[其他 → authc] F --> I[允许访问] G --> J[验证通过则放行] H --> K[强制登录]1.7 自定义过滤器增强安全性
可编写自定义过滤器以拦截异常路径结构:
public class SecurePathFilter extends AccessControlFilter { @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { String uri = ((HttpServletRequest)request).getRequestURI(); if (uri.contains(";") || uri.contains("..")) { return false; } return true; } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setStatus(403); return false; } }1.8 运行时监控与日志审计
建议开启 Shiro 的调试日志,并记录所有被拦截的请求:
日志项 建议级别 说明 Filter chain matched for request DEBUG 用于追踪匹配路径 Authentication required INFO 记录未授权访问尝试 Path contains suspicious characters WARN 触发自定义过滤器告警 User logged in successfully INFO 关键操作审计 Permission denied WARN 潜在攻击行为 1.9 框架集成建议与最佳实践
在 Spring Boot 中整合 Shiro 时,推荐通过 Java Config 方式定义 Filter Chain,提升可维护性:
@Bean public ShiroFilterFactoryBean shiroFilter() { ShiroFilterFactoryBean factory = new ShiroFilterFactoryBean(); Map<String, String> filterChain = new LinkedHashMap<>(); filterChain.put("/login", "anon"); filterChain.put("/static/**", "anon"); filterChain.put("/admin/**", "authc, roles[admin]"); filterChain.put("/api/**", "authc"); filterChain.put("/**", "authc"); factory.setFilterChainDefinitionMap(filterChain); return factory; }1.10 持续安全评估与自动化测试
建立自动化测试用例模拟常见绕过手法:
- 发送带有
%252F编码的请求 - 构造包含
;的路径 - 尝试访问
/./admin或/admin/. - 验证未授权用户是否能访问
/api/user.json - 检查日志中是否存在可疑路径记录
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 通过添加分号(;)构造恶意路径,如