JWT安全测试终极指南:从原理到实战的漏洞挖掘与防御 1. 项目概述为什么JWT安全测试是Web安全的必修课在今天的Web应用和API开发中JSON Web TokenJWT几乎成了身份验证和授权的标准方案。它结构清晰、无状态、易于跨域开发者们爱不释手。但就像一把锋利的双刃剑如果配置不当或实现有误JWT本身就可能成为整个安全体系中最脆弱的一环。我见过太多项目前端后端调得飞起功能一切正常却因为一个JWT的签名算法被设置为none或者密钥硬编码在客户端导致整个用户体系被轻易绕过。这绝不是危言耸听在真实的渗透测试和漏洞赏金项目中与JWT相关的安全问题一直是高频出现且回报丰厚的突破口。所以这个“终极指南”的目的不是简单地罗列几个漏洞类型而是带你像一名真正的安全工程师一样系统性地审视JWT。我们将从最基础的Token结构解码开始一步步深入到签名伪造、算法混淆、密钥破解等高级攻击手法并配合Burp Suite、jwt_tool等实战工具构建一套完整的从扫描到渗透的测试流程。无论你是刚入门的安全测试新手还是想巩固JWT安全知识体系的开发人员这份指南都将提供可直接上手操作的路径和必须绕开的那些“坑”。2. JWT核心安全机制深度解析与攻击面映射在动手测试之前我们必须彻底理解JWT的安全机制究竟建立在什么之上以及攻击者会从哪些角度去撬动它。JWT通常由三部分组成头部Header、载荷Payload和签名Signature通过点号.连接形如xxxxx.yyyyy.zzzzz。其安全性核心在于签名部分它确保了Token的完整性和真实性。服务器使用一个密钥对于HMAC算法或一对公私钥对于RSA/ECDSA算法对“头部载荷”进行签名生成签名部分。验证时服务器用同样的逻辑重新计算签名并与Token中的签名比对一致则通过。2.1 签名算法安全的第一道也是最后一道防线JWT头部中的alg算法声明是整个安全链条的起点。常见的算法有HS256使用同一个密钥进行签名和验证。速度快但密钥管理是命门。一旦密钥泄露攻击者可以签发任意Token。RS256使用私钥签名公钥验证。公私钥分离更安全但计算开销稍大。ES256基于椭圆曲线的数字签名算法在提供与RS256相当安全性的同时密钥更短性能更好。none这是一个致命的“特性”。声明算法为none意味着不需要签名。如果服务器配置错误接受了alg: none的Token那么攻击者可以随意篡改载荷。注意这里隐藏着一个巨大的陷阱——“算法混淆攻击”。如果服务器代码在验证Token时依赖于Token头部自声明的alg值来选择验证逻辑就可能出问题。例如服务器本应只接受RS256签名的Token但验证代码逻辑是if alg “RS256”: 用公钥验证 else if alg “HS256”: 用密钥验证。攻击者可以将alg改为HS256然后将原本的RS256公钥当作HMAC的密钥去伪造一个签名。因为公钥通常是公开的攻击者就能用这个公开的公钥作为“密钥”成功伪造一个服务器会接受的HS256Token。其根本原因是验证逻辑没有将预期的算法固定死。2.2 标准声明与业务逻辑漏洞载荷中的声明是另一个主要攻击面。除了自定义的业务字段JWT标准定义了一些保留声明Reserved Claims它们的错误处理会引发漏洞exp过期时间服务器必须检查当前时间是否超过此时间戳。不检查或检查逻辑有误如只检查是否存在该字段会导致Token永不过期。nbf生效时间和iat签发时间类似exp逻辑缺陷可能导致时间校验被绕过。iss签发者和aud受众用于校验Token的颁发者和目标接收者。如果服务器不验证iss攻击者可能使用来自其他系统的、泄露的但未过期的Token来访问你的系统。如果不验证aud一个发给服务A的Token可能被用来访问服务B。jtiJWT ID用于实现Token一次性使用或吊销列表。如果缺乏jti或对应的吊销检查机制Token一旦签发就无法主动使其失效在被盗后会造成持续风险。2.3 密钥的脆弱性从生成到存储对于HS256这类对称算法密钥就是一切。弱密钥如短密钥、常见单词、与项目名相关极易被暴力破解。密钥硬编码在客户端代码或配置文件中等于拱手送人。即使使用RS256私钥的存储位置代码、配置文件、环境变量、硬件安全模块HSM和保护方式文件权限、加密存储也至关重要。此外密钥从不轮换意味着一个密钥泄露所有历史签发的Token在过期前都可能存在风险。通过以上分析我们可以绘制出JWT的核心攻击面地图令牌本身结构解析、敏感信息泄露、未签名/弱签名。验证逻辑算法支持不当如接受none、算法混淆、声明校验缺失expissaud。密钥体系弱密钥、密钥泄露、密钥管理不当、缺乏轮换。使用上下文Token存储不安全客户端、传输未加密未使用HTTPS、缺乏吊销机制、重放攻击防护。3. 实战环境搭建与核心测试工具链配置理论清晰后我们需要一个可以安全地进行破坏性测试的环境。我强烈建议使用容器化技术如Docker来搭建一个包含漏洞的靶场应用这样既能模拟真实场景又不会影响你的生产或开发环境。3.1 搭建靶场一个存在JWT漏洞的Web应用这里我们使用一个经典的、专为JWT安全学习设计的靶场json-web-tokens-vulnerable-app。它集成了多种常见的JWT错误配置。# 1. 拉取靶场镜像 docker pull blabla1337/owasp-skf-lab:json-web-tokens # 2. 运行容器映射端口到本地 docker run -d -p 127.0.0.1:5000:5000 --name jwt-lab blabla1337/owasp-skf-lab:json-web-tokens # 3. 访问靶场 # 浏览器打开 http://localhost:5000这个靶场提供了多个关卡每个关卡演示一种特定的JWT漏洞例如“未验证签名”、“弱密钥”、“none算法”等。它是我们后续所有实战操作的沙盒。3.2 构建你的JWT安全测试工具箱工欲善其事必先利其器。以下是我在日常渗透测试和代码审计中高频使用、并强烈推荐的工具链1. 拦截与修改代理Burp Suite Professional / OWASP ZAP这是测试的“指挥中心”。Burp Suite是行业标杆其Repeater重放、Intruder入侵者用于爆破和模糊测试、Scanner扫描器模块对JWT测试至关重要。社区版功能受限但Repeater和Intruder基础功能可用。OWASP ZAP是强大的免费开源替代品。配置要点在浏览器和Burp中正确配置代理通常127.0.0.1:8080并安装Burp的CA证书到浏览器以拦截HTTPS流量。2. 专用JWT操作与攻击工具jwt_tool这是一个用Python编写的、功能极其强大的命令行工具。它几乎能完成所有JWT相关的测试操作。# 安装 git clone https://github.com/ticarpi/jwt_tool cd jwt_tool pip install -r requirements.txt # 或者直接使用python3 jwt_tool.py它的强大之处在于一体化解码、验证、篡改、生成、多种攻击模式none攻击、混淆攻击、爆破等都可以通过命令行参数快速完成。3. 在线解码与调试jwt.io这是一个非常直观的在线网站。当你拿到一个Token时第一时间可以粘贴到这里它能自动解码头部和载荷并以JSON格式清晰展示。你可以直接在线编辑载荷并看到编码后的Token变化。但切记绝对不要在此网站处理任何生产环境的真实Token或敏感密钥因为它是一个第三方服务。4. 浏览器插件JWT Inspector当你需要频繁在浏览器开发者工具和Burp Suite之间切换查看Token时这个插件能极大提升效率。它自动检测页面请求和本地存储中的JWT并提供一个友好的界面进行查看、解码和编辑。5. 编程库PyJWT (Python)对于需要自动化、定制化测试脚本的场景PyJWT库是首选。你可以用它编程生成、签名、验证Token模拟各种异常情况。pip install pyjwt6. 密钥爆破工具hashcat如果怀疑使用的是弱密钥签名HS256hashcat是离线暴力破解的王者。你需要先使用jwt_tool将JWT转换成hashcat兼容的格式然后利用强大的GPU算力进行破解。# 使用jwt_tool生成hashcat格式 python3 jwt_tool.py JWT_TOKEN -C -d /path/to/wordlist.txt # 上述命令会给出hashcat的攻击模式和hash格式然后使用hashcat执行实操心得工具不在多在于精通。我的日常流程是用Burp拦截流量 - 发现JWT - 用jwt.io快速看一眼结构 - 如果有深入测试需求复制Token到jwt_tool进行自动化扫描和攻击尝试 - 针对特定疑点如弱密钥用hashcat进行爆破。将这几个工具串联起来就形成了一条高效的测试流水线。4. 完整漏洞扫描流程从信息收集到深度探测现在我们假设你面对一个全新的Web应用或API你的任务是系统性地评估其JWT实现的安全性。下面是一个可操作的、步步为营的扫描流程。4.1 第一步信息收集与Token捕获首先你需要获取到一个有效的JWT Token。正常流程获取使用测试账号完成登录流程。通过Burp Suite代理在HTTP历史记录中寻找登录后的请求。Token通常出现在以下位置Authorization头Authorization: Bearer JWT_TOKENCookieCookie: sessionJWT_TOKEN或Cookie: tokenJWT_TOKEN请求体POST请求的JSON或表单数据中。URL参数较少见但不无可能如?access_tokenJWT_TOKEN。解码与初步分析将捕获到的Token复制到jwt.io或使用jwt_tool解码。python3 jwt_tool.py JWT_TOKEN这个命令会漂亮地打印出头部和载荷的JSON内容。此时你需要像侦探一样审视这些信息头部alg是什么是HS256、RS256还是其他typ通常是JWT。有没有其他自定义字段载荷有哪些标准声明expiatissaudsubjti它们的值是否合理有哪些自定义业务声明如user_idroleemail这里可能直接泄露敏感信息我曾见过把用户密码哈希、API密钥甚至数据库连接字符串放在载荷里的案例这是严重的设计缺陷。4.2 第二步基础安全性快速扫描使用jwt_tool的扫描模式可以一键完成多项基础检查。python3 jwt_tool.py JWT_TOKEN -t http://target.com/api/protected-endpoint -rc “Cookie: sessionJWT_TOKEN”-t指定目标URL用于发送修改后的Token测试响应。-rc指定请求Cookie工具会自动替换其中的Token。工具会自动测试none算法攻击将alg改为none移除签名发送测试。未验证签名篡改载荷如将user_id改为其他值但保持原签名不变发送测试。如果服务器接受了说明它根本没验证签名密钥混淆攻击尝试将alg从RS256改为HS256并用已知的公钥文件作为密钥进行签名伪造。弱密钥爆破尝试一个内置的常见弱密钥列表如secretpassword123456等。4.3 第三步声明校验逻辑深度测试自动化工具可能无法覆盖所有业务逻辑。你需要手动测试每个关键声明的校验是否严格。过期时间exp绕过使用jwt_tool或PyJWT将一个已过期Token的exp值改为未来的时间戳。或者更隐蔽地直接删除exp字段。有些糟糕的实现只检查exp是否存在如果不存在就跳过检查。将修改后的Token替换到请求中重放观察是否还能访问资源。签发者iss与受众aud绕过修改iss值为一个任意字符串或另一个已知的、受信任的签发者如果从其他渠道获知。修改aud值尝试访问本不该由此Token访问的另一个服务或接口路径。测试服务器是否返回如Invalid issuer或Invalid audience的错误。如果不返回或者修改后依然能访问则存在漏洞。权限提升垂直越权这是最危险的漏洞之一。在载荷中寻找如roleisAdminprivileges等字段。将一个普通用户的role: user修改为role: admin然后重新编码Token注意需要解决签名问题。如果签名验证不严或存在算法漏洞这可能成功。使用jwt_tool的篡改功能非常方便python3 jwt_tool.py JWT_TOKEN -T -pc “role” -pv “admin”-pc指定要修改的声明名-pv指定新值。工具会生成篡改后的Token你需要用Burp Repeater手动测试。重放攻击测试简单直接在Token有效期内多次使用完全相同的Token和请求参数访问同一个需要授权的端点。观察服务器是否接受。如果每次都返回相同成功结果且没有计数器或一次性令牌机制则存在重放攻击风险。防御措施通常包括使用jti声明、请求时间戳校验或服务端Token一次性使用记录。4.4 第四步密钥强度与算法测试弱密钥暴力破解针对HS256 如果算法是HS256且自动化弱密钥扫描没成功你可能需要进行大规模的字典爆破。首先用jwt_tool将Token转换成hashcat模式python3 jwt_tool.py JWT_TOKEN -C命令会输出类似HMAC-SHA256的哈希值和推荐使用的hashcat模式如16500。准备一个强大的密码字典如rockyou.txtSecLists中的相关字典。使用hashcat命令进行爆破hashcat -m 16500 hash_file /path/to/wordlist.txt -O -w 3如果成功hashcat会输出破解出的密钥。算法安全性评估检查alg声明。绝对不应该支持none。HS256的密钥长度至少应为256位32字节并且是密码学安全的随机数。对于RSARS256RS384RS512密钥长度至少应为2048位推荐3072位或以上。关注是否有降级攻击的可能服务器是否同时支持强算法如RS256和弱算法如HS256这为算法混淆攻击创造了条件。5. 高级渗透技巧绕过签名与逻辑漏洞利用当基础扫描未能发现明显漏洞时我们需要祭出更高级的技巧这些往往能发现深层次的、逻辑性的安全问题。5.1 密钥混淆攻击的多种变体我们之前提到了基本的RS256到HS256的混淆。但实际情况可能更复杂。场景一服务器使用JWKSJSON Web Key Set端点。这是一个公开的URL如/.well-known/jwks.json用于发布验证Token的公钥集合。攻击者可以从JWKS端点获取公钥。伪造一个JWKS端点将自己的恶意公钥放入。篡改Token将alg改为RS256但使用自己的私钥签名。同时修改Token头部的kid密钥ID参数指向自己伪造的JWKS中的密钥ID。如果服务器在验证时根据kid动态地从Token中指定的来源如果实现不安全获取公钥就可能使用攻击者的公钥验证通过攻击者私钥签名的Token。场景二多种算法支持与密钥IDkid注入。kid参数用于在多个密钥中指定使用哪一个。如果服务器端的密钥检索逻辑存在路径遍历或SQL注入等漏洞攻击者可能通过操纵kid值让服务器使用一个攻击者已知的密钥如一个静态文件来进行HMAC验证。例如设置“kid”: “../../../../dev/null”服务器可能会尝试从该路径读取“密钥”而/dev/null的内容是已知的空攻击者就可以用空密钥伪造HMAC签名。5.2 基于时间的攻击与条件竞争这类攻击利用服务器在时间校验上的微小延迟或不一致性。nbfNot Before绕过有些服务器可能只在Token首次使用时检查nbf之后缓存验证结果。攻击者可以尝试在nbf时间点之前一点点发送Token并快速重放可能绕过检查。时钟漂移利用服务器集群中如果各节点系统时钟不同步在一个节点上已过期的Token在另一个时钟较慢的节点上可能仍被接受。测试时可以尝试在exp过后立即重试有时能成功。5.3 签名验证逻辑缺陷这是代码层面最深层的漏洞。签名未验证最极端情况服务器解码了头部和载荷后直接信任其中的内容跳过了签名验证步骤。任何篡改都能成功。验证结果处理错误例如调用的JWT库验证函数返回一个对象代码错误地检查了对象是否存在而非验证是否成功。# 错误示例 try: decoded jwt.decode(token, key, algorithms[‘RS256’]) # 验证失败会抛出异常 # 如果验证失败根本不会执行到这里 if decoded: # 这个检查是多余的永远为True return success except Exception: return fail这段代码看起来没问题但问题在于如果密钥错误或签名无效jwt.decode会直接抛出异常。但如果有某种方式让验证函数不抛异常而返回None或False例如某些库的特定配置或错误使用那么if decoded:检查就可能让无效Token溜过去。密钥来源不可控服务器从数据库、配置文件或环境变量获取密钥时如果攻击者能通过其他漏洞如SQL注入、文件读取、SSRF篡改或泄露这个密钥整个JWT体系就崩溃了。6. 防御方案设计与安全开发实践在进行了全面的攻击测试之后我们自然要知道如何构建一个健壮的JWT系统。防御不是单点而是一个体系。6.1 安全的JWT实现清单使用强算法并固定算法强制使用RS256、ES256等非对称算法并在验证代码中显式指定算法列表绝不信任Token头中的alg。# Python PyJWT 正确示例 import jwt public_key open(‘public.pem’).read() # 关键algorithms参数必须明确指定且只包含你信任的算法 payload jwt.decode(token, public_key, algorithms[‘RS256’])绝对不要使用algorithmsNone或jwt.decode(token, key)不指定算法。严格校验所有标准声明expnbfiat必须校验且使用可靠的服务器时间。issaud必须校验值与预配置的完全匹配。jti考虑使用并结合服务端存储实现Token吊销清单黑名单。虽然这引入了状态但对于关键操作如登出、密码修改后立即使旧Token失效是必要的。安全的密钥管理HS256密钥必须是高熵随机字符串长度足够32字节通过安全的环境变量或密钥管理服务如AWS KMS HashiCorp Vault获取绝不能硬编码。RS256/ES256私钥必须被严格保护类似HS256密钥。公钥可以安全地分发。密钥轮换制定并执行密钥轮换策略。轮换后旧密钥应在所有相关Token过期后废弃。Token的安全传输与存储传输始终使用HTTPS。考虑将Token放在Authorization: Bearer头中避免放在URL里可能被日志记录。客户端存储对于单页应用SPA可以存储在HttpOnly、Secure、SameSiteStrict的Cookie中这能有效防御XSS攻击窃取Token。也可以存储在内存中如Vue/React状态但页面刷新会丢失。避免存储在localStorage或sessionStorage中它们对XSS攻击毫无抵抗力。实施额外的防御层请求指纹将用户IP、User-Agent的一部分哈希后放入Token或与Token关联服务端进行二次校验增加Token盗用的难度。短期有效期设置较短的exp如15-30分钟并结合使用刷新令牌Refresh Token机制来获取新的访问令牌。刷新令牌应有更长的生命周期但存储和使用需更加小心如仅用于特定的令牌刷新端点且可被吊销。6.2 开发与测试流程中的安全卡点安全是设计出来的不是测试出来的。在开发阶段就应融入安全实践代码审查将JWT验证代码作为安全审查的重点。检查算法指定、声明校验、密钥获取等关键点。依赖项扫描定期使用npm auditpip-auditOWASP Dependency-Check等工具扫描JWT相关库如jsonwebtokenpyjwt的已知漏洞。自动化安全测试在CI/CD流水线中集成SAST静态应用安全测试工具以及针对JWT的专项安全测试脚本例如使用jwt_tool对测试环境的API进行自动化扫描。7. 典型漏洞场景实战复现与排查记录让我们通过两个我在实际测试中遇到的经典案例来串联前面的知识。7.1 案例一算法设置为“none”导致全线崩溃场景一个内部管理系统的API使用JWT进行鉴权。测试过程使用测试账号user: test, password: test123登录Burp捕获到返回的TokeneyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...。在jwt.io解码发现头部{“alg”: “HS256”, “typ”: “JWT”}载荷包含{“user”: “test”, “role”: “user”, “exp”: 1742…}。使用jwt_tool进行快速扫描python3 jwt_tool.py eyJhbG... -t http://internal-api/admin/users -rc “Authorization: Bearer eyJhbG...”。扫描报告显示“none算法攻击”测试成功工具自动将alg改为none删除了签名并用这个新Token访问了/admin/users端点服务器返回了200 OK和用户列表数据。手动验证用jwt.io将头部改为{“alg”: “none”, “typ”: “JWT”}将载荷中的“role”: “user”改为“role”: “admin”将第三部分的签名置空。将生成的xxxxx.yyyyy.注意最后有一个点格式的Token替换到请求中成功以管理员身份访问所有接口。根源分析后端使用的是某个旧版本JWT库且解码代码写成了jwt.decode(token, verifyFalse)或等效形式完全跳过了签名验证。攻击者可以伪造任意用户的任意权限。修复建议升级JWT库并在解码时强制启用签名验证并指定算法jwt.decode(token, key‘your-secret’, algorithms[‘HS256’])。7.2 案例二密钥硬编码与弱密钥爆破场景一个移动应用的后端API。测试过程反编译移动应用APK文件在资源文件或Java代码中搜索secretkeyjwt等关键词。发现一处代码String jwtSecret “MySuperSecretKey123!”;。这很可能就是HMAC的签名密钥。为了验证我们使用这个密钥用PyJWT伪造一个Token。import jwt secret “MySuperSecretKey123!” forged_payload {“user_id”: 1, “is_admin”: True, “exp”: 9999999999} forged_token jwt.encode(forged_payload, secret, algorithm‘HS256’) print(forged_token)将生成的Token用于API请求果然获得了管理员权限。延伸测试即使没有找到硬编码密钥如果算法是HS256也可以尝试弱密钥爆破。收集目标公司名称、项目名、常用技术栈等组合成字典用hashcat进行爆破有时在几分钟内就能破解出诸如companyname2024project_secret这类弱密钥。根源分析开发人员将密钥视为普通配置写死在客户端或服务端代码中且密钥强度不足。修复建议立即在服务端轮换新的、强随机密钥。将密钥从代码中移除通过安全的配置管理服务或环境变量注入。对于移动应用等无法完全保密客户端密钥的场景应考虑改用非对称加密如RS256或采用更安全的令牌交换流程如PKCE。8. 工具链深度集成与自动化测试脚本编写对于需要持续进行安全评估的大型项目手动测试效率太低。我们需要将工具链集成并编写自动化脚本。8.1 使用Burp Suite扩展进行被动扫描可以编写自定义的Burp Suite扩展使用Java或Python在代理流量中自动识别JWT并执行一系列基础测试如none算法测试、无效签名测试、过期时间测试。当检测到潜在漏洞时自动在Burp的Issues面板中创建警报。8.2 基于Python的自动化测试脚本示例下面是一个简单的脚本框架使用pyjwt和requests库对目标API的JWT实现进行自动化测试。import requests import jwt import time import json from typing import Dict, Optional class JWTAuditor: def __init__(self, base_url, valid_token): self.base_url base_url self.valid_token valid_token self.session requests.Session() self.session.headers.update({‘Authorization’: f’Bearer {valid_token}’}) try: self.header jwt.get_unverified_header(valid_token) self.payload jwt.decode(valid_token, options{“verify_signature”: False}) except Exception as e: print(f”[!] 无法解码初始Token: {e}”) raise def test_none_algorithm(self): “”“测试接受none算法的漏洞”“” print(”[*] 测试 none 算法…”) # 构建一个 algnone 且无签名的Token none_header {“alg”: “none”, “typ”: “JWT”} # 篡改payload例如提升权限 malicious_payload self.payload.copy() malicious_payload[“role”] “admin” # 生成无签名的Token none_token jwt.encode(malicious_payload, key“”, algorithm“none”) # jwt.encode 对于’none’算法会生成一个以’.’结尾的token # 确保格式正确 if not none_token.endswith(‘.’): none_token ‘.’ self._send_test_request(none_token, “None Algorithm”) def test_signature_verification(self): “”“测试是否验证签名”“” print(”[*] 测试签名验证…”) # 简单地修改payload中的一个字符但保持原签名这会导致签名无效 # 由于JWT的特性直接修改编码后的字符串更简单 parts self.valid_token.split(‘.’) if len(parts) ! 3: print(”[!] Token格式错误”) return # 解码并篡改payload malicious_payload self.payload.copy() malicious_payload[“user_id”] malicious_payload.get(“user_id”, 0) 1 # 重新编码payload部分 (不使用签名) import base64, json encoded_payload base64.urlsafe_b64encode( json.dumps(malicious_payload, separators(‘,’, ‘:’)).encode() ).decode(‘utf-8’).rstrip(‘’) # 拼接头部、篡改后的载荷和原始签名 tampered_token f”{parts[0]}.{encoded_payload}.{parts[2]}” self._send_test_request(tampered_token, “Signature Verification Bypass”) def test_exp_claim(self): “”“测试过期时间校验”“” print(”[*] 测试 exp 声明…”) # 创建一个过期时间很远的payload future_payload self.payload.copy() future_payload[“exp”] int(time.time()) 3600 * 24 * 365 * 10 # 10年后 # 我们需要用正确的密钥重新签名这里假设我们不知道密钥此测试仅当签名验证关闭时有效 # 更实际的测试是删除exp字段 payload_without_exp self.payload.copy() payload_without_exp.pop(“exp”, None) # 同样我们需要构造一个Token。这里我们仅演示逻辑实际需要根据漏洞情况调整。 print(” (此测试需要根据实际情况调整例如删除exp字段或使用已知弱密钥签名)”) def _send_test_request(self, test_token, test_name): “”“发送测试请求”“” test_headers {‘Authorization’: f’Bearer {test_token}’} try: # 假设有一个需要鉴权的端点 resp self.session.get(f’{self.base_url}/api/user/profile’, headerstest_headers) # 根据业务逻辑判断是否成功。例如状态码200且返回了用户信息可能意味着成功绕过。 # 这里需要你根据目标API的具体行为来定义“成功”的条件。 if resp.status_code 200: # 简单判断如果响应包含特定错误信息可能是失败的 if “invalid token” not in resp.text.lower() and “unauthorized” not in resp.text.lower(): print(f” [] {test_name} 可能存在问题状态码: {resp.status_code}”) else: print(f” [-] {test_name} 似乎被正确拦截。”) else: print(f” [-] {test_name} 返回状态码: {resp.status_code}”) except Exception as e: print(f” [!] 请求发送失败: {e}”) if __name__ “__main__”: # 配置 TARGET_URL “http://vulnerable-app.local” VALID_JWT “your.valid.jwt.token.here” # 从登录请求中获取 auditor JWTAuditor(TARGET_URL, VALID_JWT) auditor.test_none_algorithm() auditor.test_signature_verification() auditor.test_exp_claim() print(”[*] 基础自动化测试完成。”)这个脚本只是一个起点。你可以扩展它集成jwt_tool的命令行调用添加对audiss的测试甚至结合子域名枚举对目标所有API端点进行批量测试。8.3 持续监控与漏洞预警将JWT安全测试纳入你的常态化安全监控体系。定期如每周或每轮迭代发布前对测试环境和预生产环境的API进行自动化扫描。关注pyjwtjsonwebtoken等核心库的安全公告一旦有新的漏洞如近年来的CVE-2022-23529 CVE-2023-30583等出现立即评估你的系统是否受影响并升级修复。JWT安全是一个动态的攻防战场。作为开发或安全人员我们必须深刻理解其原理熟悉攻击者的工具和方法才能在设计和实现中构建起有效的防御。这份指南提供的路径、工具和思路希望能成为你安全测试武器库中的一件称手兵器。记住最好的安全测试是抱着“我就是攻击者”的心态去思考每一个环节是否可能被突破。