1. 背景
1.1 为什么需要防盗链?
视频资源是互联网内容的核心组成部分,但高带宽消耗和版权问题使其成为盗链攻击的主要目标:
- 成本压力:非法引用导致服务器带宽成本激增。
- 版权风险:内容被非法分发,破坏商业模式。
- 数据安全:敏感视频可能被恶意抓取或篡改。
1.2 防盗链的核心目标
- 防止未经授权的域名/应用访问资源。
- 降低资源被自动化工具爬取的风险。
- 动态控制访问权限(如按时间、用户身份限制)。
2. 现状
2.1 常见攻击手段
手段 | 描述 |
---|---|
直接盗用URL | 攻击者通过浏览器调试工具获取视频地址并嵌入自己的页面或应用。 |
爬虫抓取 | 使用自动化脚本批量下载视频资源。 |
协议破解 | 分析客户端请求逻辑,伪造合法签名或绕过认证机制。 |
2.2 现有技术方案的局限性
-
简单Referer检查:易伪造(如
curl -e "https://legit.com"
)。 - 静态Token:泄露后长期有效,无法动态失效。
- 纯前端方案:JS加密易被逆向,无法保护核心逻辑。
3. 现有技术方案
3.1 服务端方案
3.1.1 Referer 校验
-
原理:校验HTTP请求头中的
Referer
字段是否在允许的域名列表中。 -
实现(Nginx示例):
location /videos/ { valid_referers server_names *.example.com; if ($invalid_referer) { return 403; } }
-
缺点:
Referer
可伪造或被浏览器隐私设置屏蔽。
3.1.2 Token 动态签名
- 原理:URL中携带动态生成的Token,服务端验证其合法性。
-
生成规则(示例):
// 服务端生成Token(Node.js) const crypto = require('crypto'); const secret = 'your-secret-key'; const expires = Date.now() + 3600*1000; // 1小时后过期 const path = '/videos/123.mp4'; const hash = crypto.createHmac('sha256', secret) .update(`${path}:${expires}`) .digest('hex'); const token = `${expires}-${hash}`; // 最终URL: https://cdn.com/videos/123.mp4?token=${token}
-
验证逻辑:服务端解析
token
,重新计算哈希并比对,同时检查时间有效性。
3.1.3 时间戳+时效控制
-
原理:URL包含过期时间戳,服务端拒绝过期请求。
https://cdn.com/video.mp4?expires=1625097600&signature=abc123
- 增强点:结合IP地址或用户ID生成签名,防止URL共享。
3.1.4 云服务商方案
- 阿里云/腾讯云:开启Referer黑白名单、URL鉴权(TypeA/B/C)。
- AWS CloudFront:基于Signed URLs或Signed Cookies的访问控制。
3.2 客户端方案
3.2.1 前端动态加载
-
实现:通过AJAX获取临时视频URL,动态插入
<video>
标签。fetch('/api/get-video-url?videoId=123') .then(res => res.json()) .then(data => { const video = document.createElement('video'); video.src = data.url; video.setAttribute('controls', true); document.body.appendChild(video); });
- 缺点:无法防御直接调用API的恶意爬虫。
3.2.2 加密分片(HLS/DASH)
- 原理:使用HLS加密(如AES-128)或DRM(Widevine、FairPlay)。
-
流程:
- 视频分片加密,密钥存储于服务端。
- 客户端播放前通过授权接口获取密钥。
- 原生播放器(如iOS AVPlayer、Android ExoPlayer)自动处理解密。
3.2.3 Web端混淆
-
技术点:
- 动态生成
<video>
标签,禁用右键菜单。 - 定时检测
document.referrer
,若不在白名单则暂停播放。 - 使用WebAssembly执行关键校验逻辑,增加逆向难度。
- 动态生成
3.3 移动端增强方案
3.3.1 证书绑定(SSL Pinning)
- 作用:防止中间人攻击,确保App只与合法服务器通信。
-
实现(Android OkHttp示例):
val certificatePinner = CertificatePinner.Builder() .add("cdn.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAA=") .build() val client = OkHttpClient.Builder() .certificatePinner(certificatePinner) .build()
3.3.2 请求头注入
- 原理:在Native层为每个视频请求添加动态Header。
-
示例(iOS):
let config = URLSessionConfiguration.default config.httpAdditionalHeaders = [ "X-Auth-Token": generateToken() ] let session = URLSession(configuration: config)
3.3.3 代码混淆与反调试
-
工具:
- Android:ProGuard、R8、DexGuard。
- iOS:LLVM混淆、反调试检测(
ptrace
)。
4. 具体实施步骤
4.1 服务端配置
步骤1:启用Referer过滤
-
Nginx:配置
valid_referers
,阻断非法来源。 - CDN控制台:开启Referer黑白名单(如阿里云CDN)。
步骤2:实现Token签名
-
生成逻辑(Python示例):
import hmac import hashlib import time def generate_token(path, secret, expire_seconds=3600): expires = int(time.time()) + expire_seconds message = f"{path}:{expires}".encode('utf-8') signature = hmac.new(secret.encode('utf-8'), message, hashlib.sha256).hexdigest() return f"{expires}-{signature}"
步骤3:设置CORS
- 限制
Access-Control-Allow-Origin
为可信域名,防止跨域攻击。
4.2 前端实现
步骤1:动态URL加载
// 从后端获取带签名的视频URL
async function loadVideo(videoId) {
const res = await fetch(`/api/video-token?videoId=${videoId}`);
const { url } = await res.json();
const videoElement = document.getElementById('videoPlayer');
videoElement.src = url;
}
步骤2:混淆关键逻辑
- 使用Webpack将核心校验代码打包为独立Chunk。
- 注入环境检测(如禁止在iframe中播放)。
4.3 移动端实现
步骤1:请求签名(Android Retrofit示例)
interface VideoApi {
@GET("video/{id}")
suspend fun getVideoUrl(
@Path("id") id: String,
@Header("X-Signature") signature: String
): Response<VideoResponse>
}
// 生成签名
fun generateSignature(id: String): String {
val timestamp = System.currentTimeMillis()
val data = "$id:$timestamp"
return HMACUtils.calculateHMAC(data, SECRET_KEY)
}
步骤2:Native层解密
- 使用C++编写解密库(Android NDK/iOS C Interop),避免密钥暴露在Java/Kotlin/Swift层。
5. 测试与验证
5.1 测试用例
测试场景 | 预期结果 |
---|---|
直接访问视频URL | 返回403/404 |
修改Token中的时间戳 | 拒绝访问(签名失效) |
从非白名单域名发起请求 | 播放器加载失败 |
5.2 工具
- Postman:模拟非法Referer和过期Token。
- Charles Proxy:抓包验证移动端请求是否携带正确签名。
- OWASP ZAP:自动化安全扫描。
6. 未来趋势
- AI行为分析:通过机器学习识别异常访问模式(如突然的流量峰值)。
- 区块链存证:对非法传播的视频进行水印追踪。
- 边缘计算鉴权:在CDN边缘节点完成实时Token校验,降低延迟。
7. 总结
- 推荐方案:组合使用Token签名+时间戳+Referer校验,移动端加固请求链路。
- 持续监控:定期审计日志,更新密钥,应对新型攻击手段。
附录: