1. 事件背景与发现过程
去年参与某三甲医院小程序安全评估时,意外发现一个高危越权漏洞。该小程序承载着预约挂号、报告查询、在线问诊等核心功能,日均活跃用户超2万。在常规渗透测试中,通过修改请求参数成功绕过权限校验,实现了越权访问其他患者的电子病历和检验报告。
漏洞最初是在测试报告查询功能时发现的。正常流程下,用户只能查看自己的检验报告,但通过Burp Suite拦截请求后发现,接口仅通过前端传递的patientID参数判断权限,未在服务端做二次校验。将patientID参数值改为其他患者的ID后,服务器竟然返回了完整的检验报告PDF文件。
2. 漏洞原理深度分析
2.1 垂直越权漏洞形成机制
该漏洞属于典型的垂直越权(Vertical Privilege Escalation),根本原因是服务端接口缺乏有效的身份鉴权机制。具体问题体现在:
- 前端信任问题:小程序前端使用wx.getStorageSync('patientID')获取当前用户ID,但该值可被篡改
- 无会话校验:接口未验证请求中的session_key或token是否与patientID匹配
- 参数依赖漏洞:业务逻辑完全依赖前端传递的patientID参数
// 问题代码示例(前端) wx.request({ url: 'https://api.hospital.com/report', data: { patientID: '123456' // 可被修改为其他患者ID }, success(res) { // 获取检验报告 } })2.2 攻击链还原
完整的攻击路径如下:
- 攻击者登录自己的账号
- 使用抓包工具拦截/report接口请求
- 修改patientID参数值为目标用户ID
- 重放请求获取敏感数据
更危险的是,进一步测试发现该模式在医嘱查询、处方详情等接口同样存在,形成漏洞矩阵。
3. 漏洞验证与影响评估
3.1 渗透测试过程记录
使用以下方法验证漏洞危害性:
信息收集:
- 通过公开渠道获取医院员工工号规律
- 收集常见患者ID生成规则(如住院号格式)
批量测试:
import requests for id in range(100000,100100): r = requests.get(f'https://api.hospital.com/report?patientID={id}') if 'PDF' in r.headers['Content-Type']: print(f'成功获取患者{id}的报告')数据关联:
- 通过多接口信息拼接还原完整病历
- 获取医生账号后可查看全院数据
3.2 影响范围统计
漏洞影响评估结果:
| 数据类型 | 影响条数 | 敏感等级 |
|---|---|---|
| 检验报告 | 约18万份 | 高 |
| 电子病历 | 约9万份 | 极高 |
| 处方信息 | 约6万条 | 中高 |
4. 修复方案与实施
4.1 短期应急措施
- 接口权限重构:
// 修复后的Java代码示例 @GetMapping("/report") public ResponseEntity getReport(@RequestHeader("Authorization") String token) { String currentPatient = JWTUtil.parseToken(token).get("patientID"); if(!currentPatient.equals(request.getParameter("patientID"))){ throw new UnauthorizedException(); } // 后续业务逻辑 }- WAF规则部署:
- 添加患者ID参数格式校验规则
- 设置单IP访问频率限制
4.2 长期加固方案
权限体系重构:
- 引入RBAC权限模型
- 实现属性基访问控制(ABAC)
安全审计增强:
- 所有敏感操作记录完整日志
- 建立实时异常访问监测
开发流程优化:
- 增加安全代码评审环节
- 实施自动化API安全测试
5. 经验总结与防护建议
5.1 典型错误模式
前端信任反模式:
- 错误:认为前端参数不可篡改
- 正确:所有权限判断应在服务端完成
会话管理缺陷:
- 错误:仅依赖前端存储的用户标识
- 正确:使用签名token并校验有效期
5.2 小程序安全开发清单
必做项:
- 所有接口实施双重鉴权(token+业务参数校验)
- 敏感数据接口增加二次认证(短信验证码等)
- 实施最小权限原则
推荐项:
- 定期进行安全渗透测试
- 关键业务接口添加水印追踪
- 建立敏感操作审批流程
5.3 监控指标建议
建议部署以下监控指标:
- 同一token访问不同患者ID的频率
- 异常时间段的数据访问行为
- 高频次报告下载操作
这次事件给我们的核心启示是:医疗类小程序必须采用"零信任"安全架构,所有请求都应视为不可信,在服务端进行完整的权限校验。同时要建立多层防御体系,确保单点漏洞不会导致系统性风险。