医院电子病历越权与下载攻防全解析:从水平越权、垂直提权到JWT防线与目录穿越

简介: 本文以医院电子病历系统为案例,完整复盘一次安全测试:从水平越权(篡改ID查他人病历)、垂直越权(伪造角色提权)、JWT鉴权原理,到目录穿越与文件名枚举攻击及层层防御演进,揭示越权本质是“客户端身份不可信”的悖论,强调服务端校验、签名防护与随机化命名等关键防御实践。(239字)


前言

这篇文章的灵感来源于一次安全测试的复盘。

当时评估一套医院电子病历系统,本来只想验证自己的就诊记录能不能正常读取。

结果发现,只要改一下链接里的数字,就能看到别的患者的病历。

顺着这条线一路挖下去,从水平越权、垂直提权,到 JWT 防线、目录穿越,最后落到文件名枚举,把一套完整的越权与文件下载攻防链路完整走了一遍。

这篇文章就是这次评估的完整记录。

文中所有代码仅用于安全研究与防御学习,严禁用于任何非法用途。

个人主页:艺杯羹

1. 水平越权:改一个数字看遍全院病历

1.1. 越权是怎么发生的:链接里的那段数字

登录医院电子病历系统,点击查看自己的就诊记录。

页面正常加载,屏幕上出现了自己的检查和用药信息。

但细心观察会发现,当前病历所在网页的链接里,藏着一串数字。

这串数字不是别的,正是当前患者的 ID。

1.2. 篡改 ID:把 19 改成 18

既然链接里带着 ID,那把这个数字改掉会怎样?

把 19 改成 18,回车,屏幕上瞬间出现了另一位患者的病历。

图片说明:患者 ID 直接暴露在链接中,篡改 ID 即可读取其他同权限患者的病历。

再改成 17、16、15……一路点下去,几乎能翻遍整家医院所有普通患者的就诊记录。

这种攻击,就叫做水平越权

1.3. 为什么叫"水平":只能看到同权限的

水平越权之所以叫"水平",是因为它只能横向触达与自己权限相同的数据。

普通患者只能看到其他普通患者的病历。

而权限更高的人,比如管理员、科室主任,普通患者是看不到的。

对比项

可见范围

正常访问

仅本人病历

水平越权

所有同权限患者的病历

越权边界

无法触达更高权限的数据

也就是说,水平越权只能横向扩散,无法向上突破。


2. 垂直越权:把角色字段改成 admin

2.1. 登录抓包:发现请求里的角色字段

水平越权只能看普通患者,权限更高的数据依旧无法触及。

于是回到登录界面,重新输入用户名和密码。

在点击登录的瞬间抓包,发现登录请求里不仅带着用户名和密码。

还额外携带了一个角色字段role=user

2.2. 篡改角色:把 user 改成 admin

把请求里的 user 改成 admin,重新发包。

登录成功后,系统管理员的管理界面直接出现在眼前。

这一次,连权限最高的数据也尽收眼底。

图片说明:登录请求中的角色字段被篡改,从普通用户提权为管理员,突破权限等级边界。

这种从低权限直接提升到高权限的攻击,就叫做垂直越权

2.3. 水平越权与垂直越权的区别

对比维度

水平越权

垂直越权

攻击方向

横向(同级)

纵向(跨级)

篡改对象

数据 ID

角色 / 权限字段

触达范围

同权限数据

更高权限数据

危害程度

水平越权是"看别人",垂直越权是"当领导"。

一次是横向扩散,一次是纵向突破。


3. 越权的本质:一个不可调和的悖论

两种越权攻击看似手法不同,背后却指向同一个根因。

这个根因,本质上是一个不可调和的悖论

3.1. 悖论的两端:必须发 ID,又怕被改 ID

一方面,用户在执行操作时,必须把自己的 ID 发送给服务器。

服务器需要在后台解析用户身份,才能据此授予对应的操作权限。

另一方面,一旦用户有权限把自己的 ID 发给服务器,他就能把这个 ID 篡改成别人的。

发送 ID 与篡改 ID,在同一个请求里完成了闭环。

3.2. 悖论的核心:身份凭据不可信

悖论面向

具体表现

必须发 ID

服务器需要身份才能鉴权

能发就能改

发出去的 ID 可能被篡改

结果

越权漏洞天然存在

问题不在用户,而在"用户提交的身份信息本身不可信"。

只要服务器完全信任客户端提交的身份字段,越权就永远防不住。


4. JWT 防线:给身份加一道不可篡改的签名

4.1. 破解悖论:让身份信息"改不动"

要解决悖论,关键在于让用户没法篡改身份信息。

登录时,服务器不再依赖客户端提交的角色字段。

而是直接根据用户名,在后台数据库自动匹配用户角色。

匹配成功后,服务端把用户 ID、用户角色等信息签名成一个 token 返回给用户。

用户之后的每一次请求,都必须携带这个 token。

4.2. JWT 的三段结构:签名就是护城河

这个 token 就是JWT(JSON Web Token),目前最常见的防越权手段之一。

JWT 由三段组成,中间用点号分隔:

Header.Payload.Signature

JWT 分段

内容

作用

Header

算法类型(如 HS256)

声明签名算法

Payload

用户 ID、角色、过期时间

承载用户身份信息

Signature

用密钥对前两段签名

防篡改核心

图片说明:用户 ID 与角色被签名进 JWT,缺少服务端密钥的用户无法篡改身份信息。

4.3. 为什么无法篡改:没有密钥就签不了名

由于 JWT 是加密的,且用户无法获得对应的密钥。

所以用户一旦篡改了用户 ID 或角色,签名就会立刻失效。

服务端校验签名失败,直接拒绝请求。

import hmac
import hashlib
import base64
SECRET = "server-side-secret-key"  # 密钥只保存在服务端
def verify_token(token: str) -> bool:
    """
    校验 JWT 签名是否有效
    任何对 Header/Payload 的篡改都会导致签名不匹配
    """
    header, payload, signature = token.split(".")
    expected = base64.urlsafe_b64encode(
        hmac.new(SECRET.encode(), f"{header}.{payload}".encode(),
                 hashlib.sha256).digest()
    ).decode().rstrip("=")
    return hmac.compare_digest(expected, signature)
# 篡改 Payload 里的角色后,签名必然校验失败
token = "header.eyJyb2xlIjoiYWRtaW4ifQ.fake-signature"
print("签名有效" if verify_token(token) else "篡改被拒绝")

用户改不了 ID,也改不了角色,越权这条路被从根上堵死。


5. 目录穿越:下载文件时偷走系统文件

JWT 守住了身份这一关,但攻击者并没有放弃。

在医院系统里,还有一个功能引起了注意:下载病历报告

5.1. 下载功能的文件名参数

每次点击下载按钮,浏览器都会跳出一个新的链接。

链接的末尾往往跟着要下载的文件名。

比如:download?file=202608_10019_report.pdf

5.2. 把文件名换成系统文件

看到文件名跟着链接走,攻击者灵机一动。

如果把文件名替换成系统文件会怎么样?

无论是在 Windows 还是 Linux 系统里,都有一些系统文件存在于固定路径下。

比如 /etc 目录下的 passwd 文件,保存着 Linux 系统的用户密码信息。

把链接里的文件名直接替换成 /etc/passwd,回车。

图片说明:文件名参数未校验,被替换为系统路径后,直接下载了服务器上最敏感的隐私文件。

系统里重要的隐私文件,就这样被下载了下来。

这种通过文件名穿越目录、访问任意文件的技术,就叫做目录穿越


6. 第一轮修复:过滤特殊字符与限定目录

工程师紧急修复了这个漏洞。

6.1. 过滤掉特殊字符

第一招,不允许文件名里传递斜杠、点之类的特殊字符。

/\.. 这些路径穿越的"武器"统统被拦截。

6.2. 限制只能访问网站内部目录

第二招,限制网站应用只能访问网站内部的文件和目录。

即使构造出路径,也无法跳出应用目录去读取系统文件。

修复手段

说明

过滤特殊字符

拦截 /\..

限定访问目录

只能读取应用内部文件

校验文件类型

只允许指定扩展名

但攻击者立刻发现,这套修复存在一个漏洞。


7. 第二轮博弈:文件名规律照样能枚举

7.1. 发现文件命名规律

攻击者注意到,病历报告的文件名存在明显规律。

文件名由**月份 + 工号(患者 ID)**组成。

比如 202608_10019_report.pdf,中间的 10019 就是患者 ID。

7.2. 替换工号:依旧能下载他人文件

既然文件名有规律,那只需要把自己的工号替换成别人的工号。

依旧可以下载获得这个文件。

图片说明:过滤特殊字符后,攻击者又利用"月份+工号"的命名规律枚举下载他人文件;最终随机重命名才彻底封堵。

目录穿越虽然被堵住了,但文件却依然能被"猜"出来。

工程师这下没招了。

7.3. 终极修复:随机字符串重命名

工程师不得不使用系统生成的随机字符串来重新命名文件。

文件名变成了没有规律的一串乱码,无法再被推测。

这样一来,攻击者再也无法获得其他人的病历文件了。

防御阶段

文件命名

能否枚举

修复前

月份 + 工号

能,规律明显

修复后

随机字符串

不能,不可预测


8. 攻防演进全景总结

把整条链路串起来,可以看到一个清晰的攻防演进过程:

回合

攻击手段

防御手段

攻防结果

第 1 回合

修改 ID 水平越权

服务端校验身份

攻击者转向提权

第 2 回合

篡改角色垂直提权

JWT 签名防线

身份越权被杜绝

第 3 回合

目录穿越下载文件

过滤特殊字符 + 限定目录

系统文件被隔离

第 4 回合

文件名规律枚举

随机字符串重命名

文件无法再枚举

图片说明:从水平越权、垂直提权到 JWT 防线,再到目录穿越与文件名枚举,攻防双方围绕身份可信与文件可猜持续博弈。

每一次防御升级,都逼迫攻击者另寻出路。

而每一次攻击进化,又催生出更严密的防御。

这就是安全领域最核心的规律:攻防永远是一场没有终点的螺旋博弈


9. 写在最后

本文用医院电子病历系统这个场景,完整推演了从水平越权到文件名枚举的越权与下载攻防链路。

这些知识点并不局限于医疗系统,它们广泛存在于电商、金融、政务、企业内网等各类业务系统中。

理解越权的本质,才能真正构建起有效的身份鉴权体系。

对开发者而言,服务端鉴权、JWT 签名、文件名白名单与随机化,是企业级应用的基本功。

技术本身没有善恶,但越界使用技术有代价。

希望这篇文章能提供一个清晰的越权攻防思维框架

目录
相关文章
|
3月前
|
Web App开发 缓存 C++
Cursor 界面"结冰"了?!原因分析及解决方案
Cursor界面出现点状雪花样花屏,多因GPU硬件加速与显卡驱动兼容性问题所致。该现象常见于Electron/Chromium应用(如VS Code、Chrome等)。首选解决方案:在Runtime Arguments中启用`"disable-hardware-acceleration": true`并重启。亦可尝试清理缓存、禁用插件、更新或回退显卡驱动。
428 3
|
2月前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
3729 141
|
24天前
|
缓存 人工智能 监控
Qwen3.8-Max 深度使用实战:从 2.4 万亿参数到生产级智能体落地
Qwen3.8-Max 是阿里云通义千问 2026 年 8 月最新发布的旗舰基座模型,2.4 万亿参数 MoE 架构、1M 上下文窗口、原生多模态(文本+图像+视频),具备"自主编程十数天交付完整项目"的长程闭环能力。本文不是又一篇"怎么调 API"的入门教程,而是一线团队将 Qwen3.8-Max 从 PoC 推向生产的深度实践记录:百炼平台开通与 API Key 管理、OpenAI 兼容协议接入、多模态与 Function Calling 进阶、思考模式与上下文缓存调优、Token Plan 订阅选型、生产环境避坑实录。
|
24天前
|
数据采集 人工智能 算法
为什么你的品牌在AI里查无此人?GEO优化的五个关键动作
本文为技术实践分享,介绍AI搜索时代企业亟需的GEO(生成式引擎优化)——不同于SEO,GEO聚焦让AI“认识、信任并推荐”品牌。文章提炼罗小军提出的五大关键动作:诊断AI可见度、结构化知识资产、建设权威信源、布局场景词矩阵、建立持续监测机制,助力企业抢占AI决策入口。(239字)
|
24天前
|
数据采集 人工智能 数据挖掘
他山科研 Skills 上架 Qoder:18 个 Skills,覆盖从调研到答辩全流程
他山团队推出20项AI科研Skill,覆盖文献检索、实验设计、学术写作到论文审查全流程,已在Qoder CN技能市场上线。含论文检索、深度研究、假设生成、统计分析、科研绘图等高频工具,助力科研提效。
239 0
|
24天前
|
人工智能 自然语言处理 数据可视化
阿里千问办公上线!一句话产出 PPT、数据报表、完整网页,注册送2000积分
千问办公是阿里巴巴推出的AI原生办公平台,基于Qwen3.8大模型,支持一句话交付PPT、文档、视频、网页等成果;深度集成钉钉,打通本地文件与浏览器,覆盖桌面端、网页端及企业协同场景。千问办公官网:https://t.aliyun.com/U/805n7O
296 0
|
24天前
|
JSON 缓存 API
为什么 ACC Core 不能和 OpenAPI、MCP 或 gRPC 绑死?
ACC 提出“Core + Binding”分层治理模型:Core 定义跨协议统一的Agent能力治理语义(如风险、审批、主体等),Binding 负责将语义无损映射到 OpenAPI/gRPC/MCP 等具体协议。避免因传输方式不同导致治理含义漂移,确保同一业务能力(如创建退款)在各系统中治理一致。(239字)
|
24天前
|
弹性计算 Cloud Native 关系型数据库
外贸稳增背景下,反向海淘 SaaS 云上架构实践,中小跨境业务如何低成本扛住流量脉冲
Taocarts 是面向中小商家的反向海淘SaaS系统,基于阿里云云原生架构,提供弹性伸缩、高可用订单管理、全球CDN加速、多币种财务核算及全链路业务协同能力,助团队低成本实现稳定出海,专注选品与运营。(239字)
65 3
|
23天前
|
存储 人工智能 JSON
ComfyUI 影视级写实 AI 短片全链路落地教程|本地 AI 电影分镜渲染、时序稳定与人像一致性解决方案
本指南详解ComfyUI+FLUX+Wan2.2离线影视工业化流程:支持8G显卡,涵盖分镜生成、关键帧绘制、IP-Adapter人物统一、ControlNet姿态控制、图生视频、时序平滑与FFmpeg成片合成,全程本地部署、无水印、无限制。
|
24天前
|
数据采集 人工智能 搜索推荐
4层进阶路径:从Schema到交叉印证的内容重构方法
本文提出AI时代内容可见度提升的4层进阶路径:基础标记、答案前置与信息块化、平台分发适配、数据交叉验证迭代。核心是将内容重构为AI可直接摘录的高密度信息块,而非传统文章。
87 2

热门文章

最新文章