[Vulnerability] 存在可能导致越权风险的硬编码JWT Secret

Author: lx915Created Jul 20, 2026Updated Jul 21, 2026

描述:

本项目是一个开源项目,任何用户都能获取到该项目中的硬编码的JWT Secret。同时,使用JWT Secret默认值启动项目时并没有任何警告提示,所以大多数用户可能不会修改此JWT Secret默认值,这可能导致攻击者伪造任意用户的权限令牌,从而绕过认证与授权机制,访问受保护接口。

密钥位置:

https://github.com/eddycjy/go-gin-example/blob/4f5174ca325b37f23edadad7c88d49586816a69c/conf/app.ini#L3

漏洞类型:

  • CWE-798: Use of Hard-coded Credentials
  • CWE-321: Use of Hard-coded Cryptographic Key

可利用分析:

该项目在 conf/app.ini 第 3 行将 JwtSecret 硬编码为 233。该密钥通过 pkg/setting/setting.go 中的 SetupmapTo 方法加载并映射到 setting.AppSetting.JwtSecret,随后在 pkg/util/util.goSetup 方法中转换为 []byte,并赋值给包级变量 jwtSecret

该硬编码密钥同时流入 JWT 签发和校验逻辑:

  • JWT 签发位置:pkg/util/jwt.go:32,通过 SignedString 使用该密钥生成 Token;
  • JWT 校验位置:pkg/util/jwt.go:39,通过 ParseWithClaims 回调返回 jwtSecret 进行签名校验。

生成的 JWT Payload 包含以下字段:

  • Username:MD5 值
  • Password:MD5 值
  • ExpiresAt:过期时间
  • Issuer:固定值 gin-blog

其中,UsernamePassword 虽然经过 MD5 哈希处理,但在伪造 Token 时可由攻击者自由指定;ExpiresAt 可被攻击者设置为未来时间;Issuer 为代码中的固定常量,可被攻击者从源码中获取。因此,Payload 中不存在服务端生成的随机高熵字段,也不存在攻击者不可伪造的服务端状态信息。

请求 Token 校验链路如下:

  1. middleware/jwt/jwt.go 中的 JWT 中间件从查询参数 token 获取令牌;
  2. 调用 util.ParseToken 解析并校验 JWT;
  3. 校验流程仅验证 HMAC-SHA256 签名和 jwt-go 库内部校验的过期时间;
  4. 服务端不回查数据库,也不校验服务端会话状态;
  5. 校验成功后,中间件直接调用 c.Next() 放行请求;
  6. 校验失败时返回 401 Unauthorized

该 JWT 校验机制属于无状态 Token 校验模型。只要攻击者持有硬编码密钥 233,即可构造包含任意 Payload 且过期时间有效的合法 JWT。伪造 Token 通过校验后,攻击者即可访问所有受 JWT 中间件保护的接口。

受影响的接口包括 /api/v1/ 下的标签和文章相关接口,例如:

  • 获取、创建、修改、删除标签;
  • 获取、创建、修改、删除文章;
  • 导出、导入标签;
  • 生成文章海报。

影响:

  • 攻击者可伪造任意用户的 JWT
  • 可冒充管理员或高权限账号访问敏感接口
  • 用户身份认证机制失效
  • 可能导致数据泄露、越权操作或账户接管

修复建议:

可以将JWT Secret放入系统环境变量中或者禁止使用默认值启动项目。