iframe 的同源限制与反爬机制的冲突
一、事件背景
A域名接入了动态防护(Bot 防护、反爬虫机制),同时第三方业务B域名通过内嵌iframe的方式调用了A域名下的一个链接。
二、动态防护介绍:
动态防护(也称为 Bot 防护、反爬虫机制)是网站为了防止自动化程序(如爬虫、恶意脚本)大规模访问而采取的一种安全措施。通过先返回一段 JS 代码到客户端执行,然后生成 Cookie就是其中一种非常典型的 客户端验证机制。
🔍 原理详解:为什么需要执行 JS 来生成 Cookie?
🧠 核心思想:
服务器通过检测客户端是否具备完整的浏览器环境来判断是否为真人或自动化工具(如爬虫、Selenium 等)。如果直接请求页面,没有执行 JS,就说明不是真正的浏览器行为,可能是机器。
✅ 典型流程如下:
首次请求
- 客户端(比如浏览器或爬虫)向服务器发送 HTTP 请求。
- 服务器识别到这不是一个具有完整 JavaScript 执行能力的浏览器(比如没有 session 或者 cookie),于是不返回真实内容。
返回一段 JS 代码
- 服务器返回一个 HTML 页面,里面包含一小段 JavaScript 脚本,这段脚本通常会:
- 计算一些随机值
- 设置
document.cookie
- 或者重定向到某个带 token 的 URL
- 服务器返回一个 HTML 页面,里面包含一小段 JavaScript 脚本,这段脚本通常会:
JS 在浏览器中执行
- 浏览器执行这段 JS,生成特定的 Cookie(例如
_cf_bm
,__cfduid
,challenge
类似的 cookie) - 然后自动发起一个新的请求(可能通过
location.href
或form.submit()
)
- 浏览器执行这段 JS,生成特定的 Cookie(例如
第二次请求
- 新请求带上刚才生成的 Cookie,服务器验证这个 Cookie 是否合法。
- 如果合法,则放行,返回正常网页内容;否则继续拦截。
🧪 示例:Cloudflare 的挑战机制
以 Cloudflare 的典型 bot 防护为例:
- 当你第一次访问被保护的网站时,它会返回如下内容:
<html>
<head><title>请等待...</title></head>
<body><script>// 这里是一段混淆过的 JS 代码var s,t,o,p,b,r,e,a,f,i,n, c = document;// ... 一系列复杂计算 ...document.cookie = "cf_clearance=xxx; path=/; expires=...; Secure";location.reload(); // 刷新页面</script>
</body>
</html>
- 这个 JS 会设置一个叫
cf_clearance
的 Cookie,它是基于时间戳、随机数和哈希算法生成的。 - 下次请求带上这个 Cookie,服务器验证通过后才允许访问真实内容。
⚠️ 对爬虫的影响
这种机制对传统爬虫(如 requests、urllib)来说是一个重大障碍,因为它们无法执行 JavaScript,也就无法生成所需的 Cookie。
解决方案包括:
方法 | 描述 | 优缺点 |
---|---|---|
使用 Selenium / Playwright | 模拟真实浏览器 | 可绕过大多数 JS 验证,但资源消耗大 |
使用 Puppeteer | Node.js 控制 Chrome | 功能强大,但速度慢 |
逆向工程 JS 逻辑 | 手动提取 JS 生成 Cookie 的逻辑,用 Python 实现 | 效率高,但开发成本高且容易失效 |
使用第三方服务 | 如 Anti-Captcha、2Captcha、ScraperAPI 等 | 成本较高,但省事 |
🛡️ 举个小例子(简化版原理)
假设服务器下发以下 JS:
let t = Date.now();
let hash = btoa(t + Math.random());
document.cookie = `my_challenge=${hash}; path=/`;
location.href = '/real-content';
这段 JS 的作用是:
- 获取当前时间戳
- 生成一个 base64 编码的 hash
- 设置成 Cookie
- 自动跳转到真实页面
服务器收到 /real-content
请求时,检查是否有这个 Cookie,并验证其格式、时效等,如果没问题就放行。
✅ 总结:为什么要执行 JS 来生成 Cookie?
目的 | 说明 |
---|---|
区分浏览器和爬虫 | 浏览器能执行 JS,爬虫不能(除非模拟) |
防止滥用 | 减少机器人刷接口、刷票、DDoS 攻击等行为 |
增加爬取成本 | 增加攻击者的逆向难度和维护成本 |
提升安全性 | 可结合浏览器指纹、TLS 指纹等多维度识别 |
三、业务适配问题
如果 <iframe>
加载的是不同源的内容,浏览器会实施 同源策略,阻止以下行为:
- 父页面访问
<iframe>
的 DOM 或执行其中的 JavaScript。 <iframe>
访问或修改父页面的内容。
这就导致第三方域名下内嵌的iframe 无法加载动态防护的JS完成检验。
四、解决方案
调整动态防护策略
对来自特定来源的请求放宽限制,如加白调用的IP(IP是固定的)、加白被第三方域名调用的url、放行调用请求的某个特征(如UA、refer 等)。