某天深夜,未授问漏一个安全测试员对着目标站点随手敲下 /swagger-ui.html,权访浏览器弹出的洞原不是404,而是理扫整整齐齐的API接口列表——每个接口的参数、返回结构、未授问漏认证方式全部摊开在眼前。权访这不是洞原漏洞,这是理扫人家主动展示的?别急着下结论,你试着调用其中某个“内部接口”,未授问漏服务器居然真的权访返回了数据。这时候你才意识到:Swagger文档本身不设防,洞原等于把系统内部的理扫钥匙串挂在了大门口。
Swagger(现在叫OpenAPI)本质是未授问漏开发者的工具,用来生成接口文档、权访调试联调。洞原问题是很多团队上线前忘了关掉这个调试入口,或者图省事直接裸奔部署。攻击者只要摸到路径,就能把整个系统的API地图扒个底朝天。更麻烦的是,Swagger UI里往往带着“Try it out”功能,等于给攻击者配了个可视化攻击面板——不用写代码,点几下就能往生产环境怼请求。
原理层面看,漏洞核心不在Swagger框架本身,而在服务端的路由配置和权限校验缺失。正常情况,/swagger-ui.html、/v2/api-docs这些路径应该只在内网或测试环境开放。但很多脚手架默认开启,开发者又没在网关层做路径拦截,导致文档资源直接映射到公网。有个细节容易被忽略:即使Swagger页面打不开,直接访问/v3/api-docs或/swagger-resources也可能拿到JSON格式的接口定义——那玩意儿比HTML页面更值钱,解析起来更干净。
我见过最离谱的案例,某金融公司把Swagger暴露在公网,接口文档里直接写着“adminToken”的硬编码示例值。攻击者用这个值调用了管理后台的数据导出接口,几十万条用户记录打包带走。你说这是Swagger的锅?不,是懒惰和侥幸心理的锅。
扫描这类漏洞不需要什么高级工具。常规做法是拿目录扫描器跑一遍字典,重点看几个固定路径。但更聪明的思路是结合域名特征——比如API网关子域名的/swagger路径往往比主站更容易命中。有些扫描器会直接解析api-docs返回的JSON,自动提取所有接口路径,再批量测试未授权访问。整个过程不到十秒,一个没防护的Swagger站点就裸奔了。
防御手段倒不复杂,但得动真格。最直接的是在Nginx层加规则,把swagger、api-docs这些关键字路径全部拒掉公网IP。其次,给Swagger文档加个简单的HTTP Basic认证,哪怕密码是admin/admin123都比裸奔强——至少能挡住90%的脚本扫描。更稳妥的做法是彻底关闭生产环境的Swagger功能,用Spring Boot的话就在配置文件里把springdoc.api-docs.enabled设为false,同时确保swagger-ui依赖不打进生产包。
有个坑得提醒:很多开发环境用Docker部署,Swagger默认开启,但容器端口映射时忘了限制来源IP。还有微服务架构下,各个服务独立暴露Swagger,网关只做了转发没做过滤——这时候就得靠统一的API安全管理平台来收口了。别想着靠开发者自觉,安全策略得靠强制手段落地。
说到底,Swagger未授权访问是个“低技术门槛、高破坏潜力”的漏洞。它不像SQL注入那样需要构造复杂payload,也不像反序列化漏洞那样依赖特定版本。它就是一道没上锁的厨房门——里面食材调料随便拿,至于能做出什么“菜”,全看闯进来的人厨艺如何。而你的任务,是确保这道门永远只在需要的时候,对需要的人敞开。