一个签名密钥,被塞进了它自己签名的那个Cookie里。这不是比喻,是字面意思。
安全研究者在对谷歌开发者文档站做常规OAuth流程梳理时,发现了一个足以拿下9万美元赏金的远程代码执行漏洞。整个攻击链的起点,是developers.google.com上一个约1200字节的Flask会话Cookie。
正常来说,一个用来存CSRF令牌和返回地址的Cookie,几百字节就够了。1200字节意味着里面塞了别的东西。研究者把它解码了。
Cookie里藏着什么
Flask的会话Cookie是签名而非加密的,任何拿到Cookie的人都能直接读出内容。解码后,里面是一个pickle序列化的oauth2client.client.OAuth2WebServerFlow对象,字段里明明白白躺着谷歌的OAuth client_id和client_secret。
一个客户端密钥泄露在Cookie里,本身已经是一个漏洞。但真正致命的是下一步。
研究者试着把这个client_secret当作Flask的SECRET_KEY来用,结果Cookie上的签名验证通过了。签名密钥,就存在它签名的那个对象里面。
为了排除巧合,研究者离线重算了签名。Flask通过itsdangerous库、用cookie-session做密钥派生,重算出来的签名和服务器发来的Cookie上的签名逐字节一致。翻转签名里的一个字符,被拒绝;用恢复出的密钥重新签名原始载荷,被接受。
会话完整性,到此彻底失效。攻击者可以设置会话里的任意键值,同时生成服务器认可的签名。
从伪造Cookie到代码执行
OAuth回调流程会从会话里读回flow对象,然后执行pickle.loads。这条链路是:验证Flask签名、读取flow条目、base64解码、反序列化。
pickle.loads只有在没人能伪造有效Cookie时才称得上"安全"。密钥一旦公开,这个前提就不存在了。研究者构造了自己的会话,用自选的CSRF令牌,把任意pickle数据塞进对应的flow键下。state参数也是攻击者可控的,服务器端不需要任何东西对齐。
pickle的REDUCE操作码会指定一个可调用对象及其参数,反序列化时直接调用它。公开的签名密钥加上这个执行点,等于无需认证的远程代码执行。
研究者没有在谷歌生产环境上跑命令,而是用时间证明。载荷简化为time.sleep(N),同一个伪造会话,只改数字:
- time.sleep(0) → 0.207秒
- time.sleep(3) → 3.193秒
- time.sleep(5) → 5.194秒
- time.sleep(8) → 8.283秒
响应时间精确跟随pickle里的数字,只有服务器真的导入了time并调用了sleep(N)才会这样。
随后是一组对照测试,排除慢接口或抖动的可能:不带Cookie,返回"Invalid request";签名翻转一个字节,返回"Invalid request";签名有效但没有flow条目,返回"Invalid request state";签名有效且带真实flow,走到谷歌令牌交换环节,在伪造的授权码上以"invalid_grant"失败;签名有效且带sleep载荷,延迟精确等于选定的数字。
影响范围不止一个站
这不是单个应用,而是共享的DevSite平台。来自developers.google.com的密钥,能签发出在以下域名上有效的会话:
- firebase.google.com
- developer.android.com
- source.android.com
- docs.partner.android.com
一个密钥,横跨七个谷歌域名。
修复需要四件事同时到位
研究者给出了四条修复建议,任何一条都能打断攻击链:
- 轮换两个已暴露的OAuth客户端密钥,并作废所有用它们签发的会话。
- 每个部署使用独立的高熵Flask SECRET_KEY,从服务端存储读取,与任何OAuth凭据无关。
- 把OAuth flow对象留在服务端,Cookie里只放不透明的引用,不携带任何敏感信息。
- 任何跨越客户端边界的数据都弃用pickle,改用带模式校验的纯数据格式,让伪造的Cookie失去作用。
四条建议叠在一起才构成完整防线。而这次漏洞之所以成立,正是因为这四件事同时缺失——两个GET请求,最终变成了在谷歌服务器上执行代码。
时间线与赏金
报告提交后,经过分类、受理,最终定级为Normal Google Applications(T2)、S0级远程代码执行,赏金7.5万美元基础金额,乘以1.2的系数,理由是报告质量出色,最终9万美元。漏洞已修复。
研究者致谢了谷歌Bug Hunters团队和DevSite工程师。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.