文章总结: 该文档披露了HackerOne平台因Rails框架升级引发的严重信息泄露漏洞,攻击者通过访问公开报告的JSON端点可获取用户邮箱、OTP备份码等敏感数据,漏洞根因是Rails7.1序列化重复键时行为变化导致敏感字段暴露,自动化测试因JSON重解析遗漏问题,漏洞在90分钟内修复并奖励研究员25000美元,启示在于依赖升级需谨慎并改进原始响应测试。 综合评分: 95 文章分类: 漏洞分析,WEB安全,安全开发,渗透测试,安全运营
0157.Hackerone中25000美元的信息泄露
原创
Rsec Rsec
Rsec
2026年4月28日 10:58 贵州
在小说阅读器读本章
去阅读
报告来源:Hackerone报告
编号:3000510
严重程度:Critical (9.2)
汇报者:avinash_
类型:信息泄露
机构:Hackerone
漏洞概述
2025年2月19日,安全研究员 avinash_ 向 HackerOne 平台报告了一个严重级别(CVSS 9.2)的信息泄露漏洞。攻击者可通过访问已公开报告的 /reports/:id.json 端点,获取报告相关用户的邮箱、OTP备份码、手机号、GraphQL密钥、T恤尺码等大量内部敏感数据。
该漏洞在报告后不到90分钟即被确认并修复,研究员最终获得了 25,000美元的漏洞赏金及∗∗25000美元+100美元 的复测奖金。
发现过程
avinash_ 在查看 HackerOne 上一个已公开的报告时,习惯性地尝试访问该报告的 .json 端点(格式为 /reports/报告ID.json),惊讶地发现返回的 JSON 数据中包含了报告参与者的大量私密信息。
进一步测试表明:
- 只有当报告存在“摘要”(summary) 时(无论是报告方还是团队方添加的摘要),漏洞才会触发。
- 若报告人和团队成员均提交了摘要,则会同时泄露双方的敏感数据。
- 该问题影响了所有已公开或未公开的报告,只要端点可访问且存在摘要。
泄露的数据类型
研究员在报告中列出了从 .json 响应中提取到的敏感字段(部分示例):
emailchanged_password_attotp_secretallow_next_sign_in_attempt_atotp_backup_codestshirt_sizecurrent_sign_in_countrygraphql_secret_tokenoverview_token_2017account_recovery_phone_number (哈希形式)account_recovery_unverified_phone_numberaccount_recovery_phone_number_sent_ataccount_recovery_phone_number_tokentotp_enabled_atsequential_totp_failurescalendar_tokencached_reputation_for_user_profile_last_reputation_id...
这些数据足以对用户账户进行完全接管(如使用备份码绕过双因素认证、重置密码等),构成极高的安全风险。
根本原因分析
- 漏洞由 HackerOne 在 2025年2月19日 进行的一次 Rails 框架升级引发:从
6.1.7.9升级到7.1.5.1。两个版本在处理哈希(Hash)序列化为 JSON 时存在细微但致命的行为差异。
示例说明
假设有如下 Ruby 哈希:
hash = { my_key: 'my_value', 'my_key' => 'my_other_value',}
- 在 Rails 6.1.7.9 中,
hash.to_json输出:(重复键只保留后添加的值)
{"my_key":"my_other_value"}
- 在 Rails 7.1.5.1 中,输出变为:(重复键同时保留,因为 JSON 规范不区分符号和字符串键,但 ActiveSupport 现在将它们视为不同)
{"my_key":"my_value","my_key":"my_other_value"}
漏洞代码路径
HackerOne 的报告摘要序列化使用了如下 jbuilder 模板:
json.merge!(summary.json_attributes)# ...if summary.persisted? json.user do json.partial!('users/user', user: summary.user) endend
而 summary.json_attributes 方法的实现为:
def json_attributes { id:, category:, content:, updated_at:, user:, # 这里返回的是 User 对象,键为符号 :user }end
最终生成的哈希中包含了两个键:一个是符号 :user(对应整个 User 对象的全部属性,含敏感信息),另一个是字符串 "user"(对应经部分模板过滤后的安全用户信息)。
在旧版 Rails 中,序列化时只保留后出现的字符串键 "user",因此敏感数据不会出现在最终 JSON 中。升级后,两个键同时输出,导致敏感用户对象被意外暴露。
自动化测试为何未能发现?
HackerOne 使用 approvals gem 进行 JSON 结构测试,典型代码为:
verify(format: :json) { subject.body }
该 gem 在比较前会重新解析 JSON。而在 Ruby 解析包含重复键的 JSON 时,默认行为是只保留最后一个键的值:
JSON.parse('{"my_key":"my_value","my_key":"my_other_value"}')=> {"my_key"=>"my_other_value"} # 前一个值被丢弃
因此,尽管实际 HTTP 响应体包含了重复键和敏感数据,但测试组件“看到”的仍然是旧版 Rails 的正常输出结构,没有任何测试失败——漏洞就这样被安全测试体系漏过了。
修复过程
- 2月21日:HackerOne 团队在收到报告后迅速部署了修复,将摘要部分的序列化逻辑改为不再合并整个 User 对象。
- 研究员复测:avinash_ 确认
.json端点仅返回用户公开信息(如姓名、个人简介),敏感字段已完全移除。 - 奖励:团队授予25000美元赏金(与该漏洞的严重性和发现速度相匹配)及100 美元复测奖金。
后续披露与透明化
该报告于 2025年4月1日 经双方同意后公开披露。HackerOne 后续还针对研究员提出的两个问题进行了回应:
- 关于是否增加原始 JSON 检查:团队表示将检讨测试策略,考虑增加对原始响应体的断言。
- 关于
as_jsonvsto_json:承认as_json可能更安全,但指出根本问题在于数据结构设计不当,而非序列化方法本身。 - 关于 swag:研究员获得了一份 HackerOne 官方礼品。
总结与启示
- 漏洞类型:信息泄露(敏感用户字段通过重复键暴露)
- 触发条件:报告存在摘要(summary),访问 .json 端点
- 根本原因:Rails 7.1 改变了重复键哈希的 JSON 序列化行为
- 测试盲点:Approvals gem 重解析 JSON 会丢失重复键,导致误报通过
- 修复措施:删除 json_attributes 中的 user 键,仅保留部分模板渲染
- 赏金总额:25,000+100 复测奖励
这一事件再次提醒安全团队:底层依赖的微小行为变化可能在不经意间引发严重漏洞;同时,依赖“规范化”输出的自动化测试可能存在盲区,需要结合原始响应检查才能彻底覆盖。
“不是每一次升级都会带来问题,但每一次升级都值得最严格的审视。”
—— 漏洞报告人 avinash_
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Rsec Rsec Rsec《0157.Hackerone中25000美元的信息泄露》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论