Swagger未授权访问,授权说白了就是访问方案你的API文档裸奔在公网上。去年我帮一家电商公司做渗透测试,漏洞打开他们的解决Swagger UI页面,好家伙,授权删订单、访问方案改价格、漏洞拉用户手机号,解决全套接口整整齐齐列在那儿,授权连个登录框都没有。访问方案这玩意儿比弱口令还可怕,漏洞弱口令至少得猜,解决Swagger直接把你家保险柜的授权钥匙挂在门口。
漏洞根源在于Springfox或springdoc这类库,访问方案默认把/v2/api-docs和/swagger-ui.html暴露出来。漏洞很多开发图省事,直接在配置里写@EnableSwagger2,完事。生产环境压根没想着关。更坑的是,有些网关层做了权限校验,但偏偏放行了这些路径,因为“文档页面嘛,给人看的”。
解决思路分三层,按紧急程度排。
第一层:立刻关掉生产环境的Swagger。最粗暴也最有效。Springfox的话,用profile区分环境:
@Configuration @Profile("!prod") @EnableSwagger2 public class SwaggerConfig { ... } springdoc更简单,配置里加一句springdoc.api-docs.enabled=false。但注意,光关UI不够,/v3/api-docs这个JSON端点也得禁。有人只关了页面,接口文档照样能拿curl拉下来,等于白干。
第二层:如果业务上确实需要在线文档(比如给前端联调用),那就给Swagger加访问控制。别自己造轮子,直接用Spring Security的filter。我见过一个项目,给Swagger路径配了个自定义拦截器,结果只校验了路径是否包含“swagger”,攻击者改成/swagger-ui.html/../v2/api-docs就绕过去了。正确做法是配合Spring Security,对/swagger-ui/**、/v2/api-docs/**、/swagger-resources/**统一走认证流程。用Basic Auth也行,但密码别用admin/admin这种。
第三层:架构层面把Swagger和业务服务彻底隔离。你可以在网关层(比如Nginx或Spring Cloud Gateway)把这些路径全部转发到一个独立的文档服务,那个服务只能读API定义,没有任何业务数据库连接。这样就算被打穿,攻击者拿到的也只是一堆接口描述,动不了真数据。这个方案成本高,但适合接口特别多、团队又管不住手的大厂。
还有个细节容易被忽略:Swagger版本升级。老版本的Springfox存在SpEL表达式注入漏洞,攻击者能通过构造参数执行任意代码。就算你关了访问,如果依赖库版本太老,某些特殊路径仍可能触发解析。建议统一升级到springdoc 2.x,或者至少把springfox升级到2.9.2以上。
最后说个真实教训。某金融客户,开发环境开了Swagger,运维用脚本同步到生产时没改配置。结果生产环境带文档上线三个月,被安全扫描发现。他们紧急在Nginx层加了个IP白名单,只允许公司VPN访问。但没过两周,内部员工账号被钓鱼,攻击者通过VPN进到内网,直接拉走了所有API的请求参数格式,然后照着格式刷接口。这事儿说明,Swagger未授权访问不只是“信息泄露”,它是攻击者的免费地图。能关就关,不能关就锁死,别心存侥幸。