API安全实战:从SRC挖掘看未授权与越权漏洞的攻防 📅 2026/6/23 8:57:38 1. 项目概述从SRC实战看API安全最近在几个企业SRC安全应急响应中心平台上提交了几个中高危漏洞类型出奇地一致都是围绕API接口的未授权访问和越权问题。这让我意识到虽然“未授权”和“越权”是老生常谈但在API驱动的现代应用架构下它们正以新的、更隐蔽的形式出现并且危害巨大。很多开发团队在前后端分离、微服务化的过程中把注意力都放在了功能实现和性能上却忽略了API接口最基本的安全边界。今天我就结合最近的实战案例把这套“组合拳”的挖掘思路、测试手法和背后的逻辑掰开揉碎讲清楚希望能给正在入门SRC挖掘的朋友或是负责API安全的开发同学一些实实在在的参考。简单来说API接口未授权漏洞指的是本应需要认证比如登录才能访问的接口在未提供任何有效凭证的情况下直接被访问并操作成功。而越权漏洞则是在拥有一个合法低权限账户的前提下能够访问或操作本应属于其他用户水平越权或更高权限角色垂直越权的数据或功能。这两者常常相伴相生一个未授权的接口可能直接导致越权而一个设计不当的授权校验逻辑则会让越权在授权之后依然发生。对于SRC猎人而言这类漏洞逻辑清晰、危害直接、复现简单是性价比极高的目标。2. 漏洞原理与核心攻击面拆解要挖洞先得懂原理。我们不能停留在“抓个包改个ID”的层面必须理解这些漏洞为何会产生以及它们通常隐藏在哪些地方。2.1 未授权访问缺失的“门卫”你可以把API接口想象成公司大楼里的各个房间。未授权访问就相当于某个重要房间比如财务室的门锁坏了或者压根没装锁任何人都能直接推门进去。从技术实现上看导致未授权的原因主要有以下几类开发疏忽或配置错误这是最常见的原因。开发人员可能为了调试方便临时注释掉了接口的鉴权拦截器如Spring Security的PreAuthorize注解、拦截器Interceptor上线时却忘了恢复。或者在配置路由规则时错误地将本应受保护的管理员API路径排除在了安全框架的过滤规则之外。默认配置与弱口令许多中间件、运维工具或框架的管理API在安装后存在默认端口、默认路径和默认空口令/弱口令。例如我之前遇到过一个案例目标的Nacos服务发现与配置中心其管理界面虽然需要登录但用于服务发现的HTTP API接口/nacos/v1/ns/instance/list在某个旧版本下存在未授权访问漏洞可以直接拉取到所有注册服务的敏感配置信息。再比如某些Swagger、Actuator端点未做访问控制直接暴露了完整的API文档甚至执行端点。接口路径猜测与目录遍历系统可能存在一些未被前端引用的“隐藏”接口或者遵循某种规律的接口路径。攻击者通过字典爆破或分析现有接口的路径规律如/api/user/1、/api/admin/config可能直接访问到未在安全管控范围内的功能接口。认证逻辑缺陷接口声称需要认证但认证校验逻辑存在严重缺陷。例如仅检查请求中是否存在token字段而不验证其有效性或者认证逻辑依赖于前端传递的某个易篡改的参数如isAdmintrue。注意未授权访问的危害是立竿见影的。它可能直接导致数据泄露下载数据库备份、读取配置文件、系统控制执行命令、上传木马或作为进一步攻击的跳板。2.2 越权漏洞失效的“权限检查”越权漏洞发生在“门卫”检查了你的工牌认证通过但没有核对你的权限清单。你拿着A部门的门禁卡却刷开了B部门的核心机房。其核心在于服务端在处理请求时未能对当前请求发起者的身份与其所要访问的资源/操作进行充分的关联校验。主要分为两类水平越权同权越权用户A可以操作用户B的数据。最常见的就是通过修改请求参数中的ID用户ID、订单ID、文章ID来访问他人信息。例如访问/api/order/1001可以看到自己的订单将ID改为1002后竟然成功看到了别人的订单详情和收货地址。垂直越权提权低权限用户能够执行高权限用户的操作。例如普通用户通过访问/api/admin/deleteUser接口成功删除了其他用户。这通常是因为服务端仅验证了用户是否登录但没有校验用户角色ROLE或权限点Permission。越权的根本原因在于服务端完全信任客户端传参直接使用客户端提交的用户ID进行查询没有从会话Session或令牌JWT中提取当前登录用户的真实身份进行比对。权限校验粒度粗放只在进入控制器Controller时做了角色校验如PreAuthorize(“hasRole(‘ADMIN’)”)但在具体的业务方法中没有对“当前用户是否有权操作这个具体的数据实体”做二次校验。前端鉴权后端不鉴权这是致命错误。所有权限校验必须放在服务端执行前端隐藏按钮、禁用菜单仅仅是用户体验优化绝非安全措施。2.3 API安全测试的独特挑战与传统Web应用不同API特别是RESTful API的安全测试有一些特殊点无状态性很多API使用Token如JWT而非Session攻击者一旦获取Token即可在有效期内模拟用户所有操作。数据驱动输入输出多为结构化数据JSON/XML漏洞可能隐藏在复杂的JSON对象嵌套中。自动化程度高API易于被脚本批量调用这意味着一个漏洞可能被瞬间利用成千上万次。文档与调试工具暴露Swagger-UI、knife4j等API文档工具若未授权访问相当于给攻击者提供了完整的“攻击地图”。3. 实战挖掘流程与工具链理论懂了我们上实战。下面是我个人总结的一套针对API未授权/越权漏洞的标准化挖掘流程。3.1 信息收集绘制API地图信息收集的广度决定了你攻击面的宽度。主动爬取与目录扫描工具Burp Suite爬虫、dirsearch、ffuf、gobuster。方法使用Burp对目标应用进行全站爬取重点关注/api/、/v1/、/rest/、/graphql等常见API路径。同时使用目录扫描工具搭配强大的API路径字典如api-words.txt、spring-boot.txt进行爆破寻找隐藏接口。技巧分析已发现的API路径模式。如果发现/api/users/尝试/api/admins/、/api/config/。留意数字ID尝试遍历。挖掘API文档与调试端点常见路径/swagger-ui.html,/v2/api-docs,/swagger//doc.html(knife4j)/actuator,/actuator/health,/actuator/env(Spring Boot Actuator)/api-docs,/openapi.json动作直接浏览器访问这些路径。一旦发现未授权的API文档你就获得了所有接口的详细说明、参数和请求格式事半功倍。分析前端代码JS文件方法在浏览器开发者工具的Sources或Network面板中仔细查看加载的JavaScript文件。现代前端框架Vue、React通常会将API请求地址硬编码或通过配置引入JS中。搜索关键词如axios.get、fetch、/api/、http://可以找到前端使用的所有API端点。识别中间件与管理服务目标通过端口扫描nmap或网络空间搜索引擎如fofa、shodan识别目标开放的非Web端口。高风险服务Redis(6379): 未授权访问可导致数据泄露甚至服务器沦陷。MongoDB(27017): 默认无认证。Elasticsearch(9200): 未授权访问可查询所有索引数据。Jenkins(8080): 控制台可能未设置密码。Kubernetes API Server(6443, 8080): 配置不当可导致集群接管。H2 Database Console(通常嵌入在Spring Boot应用中): 未授权访问可直接执行SQL。3.2 漏洞探测从改包到逻辑分析拿到API列表后进入核心测试环节。未授权访问测试步骤对于收集到的每一个API端点在未登录状态下或使用一个无效/空的Token直接重放请求。Burp技巧使用Repeater模块。先拦截一个已登录的请求然后删除请求头中的Authorization、Cookie、X-Token等认证字段或者将其值改为一个明显错误的字符串再发送请求。判断依据如果返回了非401未认证或403禁止访问的状态码并且返回了有效数据或操作成功的提示那么极有可能存在未授权访问漏洞。需要特别注意200状态码下的“成功”信息以及302重定向可能重定向到登录页也可能重定向到内部管理页。水平越权测试前提你需要至少两个同一权限级别的测试账号如UserA和UserB。测试模型用UserA登录访问一个操作自身资源的接口如GET /api/orders/1001假设1001是UserA的订单。在Burp中捕获这个请求。在Repeater中将请求路径或参数中的资源ID如1001修改为UserB的订单ID如1002。重放请求。关键点服务端应该判断当前登录用户是UserA而请求的资源1002属于UserB因此返回403。如果成功返回了UserB的订单数据则存在水平越权。参数不限于ID除了路径参数还要检查JSON请求体、URL查询参数?id、甚至自定义请求头中是否存在标识资源归属的参数。垂直越权测试前提你需要一个低权限账号如普通用户和一个高权限账号如管理员。通常你只有普通用户账号管理功能需要靠“猜”和“试”。测试模型用普通用户登录浏览其所有功能抓取所有请求。分析管理功能的可能路径如包含admin、manage、delete、config等关键词。直接使用普通用户的会话Cookie/Token去尝试访问这些管理员API。或者观察管理员API的请求格式如果通过其他信息泄露获得尝试用普通用户的身份构造并发送相同请求。绕过前端控制如果某个按钮前端做了灰度或隐藏务必通过Burp直接构造其背后的API请求进行测试。前端限制形同虚设。3.3 工具辅助与自动化手动测试是基础但效率有限。合理利用工具可以提升覆盖面。Burp Suite 插件Autorize越权测试神器。配置好低权限用户Auth和高权限用户Unauth的请求插件会自动用低权限用户的凭证去访问高权限用户访问过的所有接口并标记出可能存在的越权返回状态码差异。JSON Web Tokens用于方便地解码、修改和重签JWT令牌测试JWT校验逻辑缺陷。自定义脚本对于ID遍历测试可以编写简单的Python脚本配合requests库批量请求/api/user/[1-10000]根据返回状态码和内容长度快速定位异常点。流量对比分析使用Burp的Compare功能对比同一个接口在登录前/后、用户A/用户B访问时的响应差异快速发现鉴权逻辑问题。4. 经典案例场景深度剖析光讲流程有点干我们结合几个我实际遇到的、以及社区公开的典型案例看看漏洞是怎么发生的。4.1 案例一调试接口泄露与未授权RCE场景在对一个Spring Boot应用进行测试时目录扫描发现了/actuator路径。访问后列出了大量端点其中/actuator/env直接展示了应用的所有环境变量包括数据库密码、云服务密钥等敏感信息。更重要的是/actuator/loggers端点允许动态修改日志级别而/actuator/heapdump可以下载内存堆转储文件。漏洞点Spring Boot Actuator端点未做安全加固直接暴露在公网且未配置独立的访问密码或将其纳入应用的安全框架管控。利用链访问/actuator发现端点列表。访问/actuator/env泄露敏感配置。在某些旧版本或特定配置下通过/actuator/loggers端点将某个关键类的日志级别设置为DEBUG可能触发敏感信息打印。通过/actuator/heapdump下载堆转储文件使用MAT等工具分析有可能从中提取出明文密码、会话信息等。修复建议通过management.endpoints.web.exposure.include严格控制暴露的端点。务必通过Spring Security对/actuator路径进行访问控制或为其配置独立的HTTP Basic认证。将Actuator端口与业务端口分离并通过网络策略限制内网访问。4.2 案例二基于ID递增的水平越权场景一个在线教育平台学生可以查看自己的学习报告。请求格式为GET /api/student/report?report_id5001。用户Areport_id从5001到5010正常访问自己的报告。将report_id改为5000成功访问到了用户B的学习报告其中包含姓名、成绩等隐私信息。漏洞点服务端代码伪逻辑如下// 错误示范直接使用客户端传来的reportId进行查询未与当前用户关联 Report getReport(String reportId) { return reportRepository.findById(reportId); // 直接查询致命 }正确的逻辑应该是Report getReport(String reportId, String currentUserId) { Report report reportRepository.findById(reportId); if (report null) throw new NotFoundException(); // 关键校验报告的所有者是否是当前用户 if (!report.getStudentId().equals(currentUserId)) { throw new AccessDeniedException(); } return report; }挖掘技巧对于任何涉及资源ID的操作养成“改一改”的条件反射。不仅是GET请求POST、PUT、DELETE请求中的ID参数同样需要测试。4.3 案例三JWT令牌解析与垂直越权场景一个系统使用JWT作为认证令牌。普通用户登录后获得一个JWT其Payload部分包含{“user”: “alice”, “role”: “user”}。通过观察发现管理后台的请求地址包含/api/admin/。直接使用普通用户的JWT令牌尝试访问GET /api/admin/user/list返回了403 Forbidden。但是访问POST /api/admin/system/config却返回了200并且成功修改了系统配置。漏洞点问题出在服务端的权限校验不一致。/api/admin/user/list这个接口可能通过注解或拦截器统一校验了角色必须为admin。而/api/admin/system/config这个接口的校验可能存在遗漏或者其校验逻辑依赖于JWT中某个可以被篡改的字段虽然JWT本身有签名但客户端无法篡改这里指服务端解析后信任了role字段但该接口的校验代码漏写了。更深层的测试即使服务端校验了角色也要检查是否存在“功能权限”层面的越权。例如管理员角色有“用户管理”和“系统配置”两个权限点。用户A是管理员但有“用户管理”权限用户B也是管理员但有“系统配置”权限。如果系统只校验了角色是admin那么用户A就能越权执行用户B的配置操作。这需要更细粒度的权限点Permission校验。JWT相关测试点修改算法为none尝试将JWT头部中的alg字段改为none并移除签名看服务端是否不验证签名就接受令牌历史漏洞现已少见。密钥混淆攻击如果服务端同时支持HS256对称加密和RS256非对称加密尝试将RS256公钥作为HS256的密钥来伪造令牌。过期时间修改虽然客户端不能篡改已签名的过期时间exp但如果服务端时间不同步或校验逻辑有误可能造成令牌长期有效。5. 防御方案与安全开发建议挖洞是为了更好的修洞。作为开发者如何避免写出有这类漏洞的API呢5.1 设计阶段最小权限与安全默认值默认拒绝所有API接口默认情况下都应该是禁止访问的。然后通过配置显式地允许哪些角色/用户访问哪些接口。而不是默认允许再逐个去限制。最小权限原则给用户、服务或进程分配完成其任务所必需的最小权限。普通用户绝对不应该拥有任何管理员接口的访问权限哪怕只是一个“只读”的管理员接口。清晰的API文档与规范在项目初期就确立API安全规范包括必须的认证、鉴权方式并将此作为代码审查的一部分。5.2 实现阶段统一的认证与鉴权中间件绝不信任客户端任何来自客户端的标识用户ID、角色、权限列表都只能作为参考绝不能作为权限判断的唯一依据。服务端必须从可信的会话存储如Redis或已验签的TokenJWT中重新获取当前用户的真实身份信息。使用成熟的安全框架充分利用Spring Security、Apache Shiro、OAuth2.0等成熟框架的能力。它们提供了声明式的权限控制如PreAuthorize、Secured和灵活的配置方式。实施RBAC基于角色的访问控制或更细粒度的ABAC基于属性的访问控制在关键的业务方法中进行二次资源归属校验。// 好的例子在Service层进行校验 Service public class OrderService { public Order getOrder(Long orderId) { Order order orderRepo.findById(orderId); String currentUsername SecurityContextHolder.getContext().getAuthentication().getName(); if (!order.getOwner().equals(currentUsername)) { throw new AccessDeniedException(“You can only view your own orders.”); } return order; } }对管理类、调试类接口进行网络隔离或强认证Actuator、Swagger、数据库控制台、运维平台等接口不应直接暴露在公网。如果必须暴露必须配置强密码非默认密码、二次验证或IP白名单。5.3 测试与运维阶段自动化安全测试将API安全测试如未授权、越权测试集成到CI/CD流水线中。可以使用OWASP ZAP、Arachni等工具进行自动化扫描。定期人工渗透测试自动化工具无法覆盖所有业务逻辑漏洞。定期邀请安全团队或外部白帽子进行深度测试。全面的日志记录与监控记录所有API访问日志特别是失败的身份验证和权限拒绝日志。设置告警规则对异常访问模式如某个用户短时间内尝试访问大量非自身资源ID进行实时告警。使用API网关在API网关层实施统一的认证、限流、黑白名单策略为后端服务提供一个统一的安全屏障。6. 写给SRC新手的入门指南如果你刚接触SRC挖掘想从API漏洞入手这里有一些具体的建议目标选择优先选择那些业务复杂、用户体系庞大、刚完成重构或采用微服务架构的新上线系统。这类系统由于开发节奏快、模块多容易出现安全配置疏忽。从“黑盒”开始无需源码专注于从外部观察和测试。熟练使用Burp Suite是你最重要的技能。把它的Proxy、Repeater、Intruder、Scanner模块玩熟。建立测试方法论按照本文的流程信息收集 - 未授权测试 - 越权测试形成肌肉记忆。对每一个抓到的请求都问自己三个问题“不登录能访问吗”未授权、“登录后能访问别人的吗”水平越权、“普通用户能访问管理员功能吗”垂直越权。保持好奇心与耐心不要只测试显而易见的/api/user/1。多关注那些看似不起眼的端点比如文件上传接口、消息通知接口、配置获取接口。一个/api/export接口可能导致全量数据泄露。学习写高质量报告漏洞的价值一半在发现一半在表达。报告要清晰描述漏洞位置、复现步骤附截图和数据包、潜在危害并给出具体的修复建议。清晰的报告能帮助厂商快速理解并修复问题也能体现你的专业性。API安全是一个纵深很长的领域未授权和越权只是入口。通过它们你可能会发现更复杂的逻辑漏洞、业务漏洞甚至链式攻击。保持学习保持好奇最重要的是始终保持对技术的敬畏和对安全的责任心。