
本文介绍一种通过 javascript 属性劫持技术实时捕获 cookie 写入操作,并结合调用栈(stack trace)精准溯源外部域名(如 domain b)向当前页面(domain a)写入 cookie 的方法。
本文介绍一种通过 javascript 属性劫持技术实时捕获 cookie 写入操作,并结合调用栈(stack trace)精准溯源外部域名(如 domain b)向当前页面(domain a)写入 cookie 的方法。
在 Web 开发中,当第三方脚本(例如托管在 domain.b 的 <script src="https://domain.b/script.js">)在当前站点(domain.a)上下文中执行并设置 document.cookie 时,浏览器默认<strong>不会暴露该 Cookie 的来源域信息。原生 API(如 document.cookie 读取)仅返回键值对,不包含设置者上下文。因此,若需审计、调试或安全合规地确认“某 Cookie 是否由特定外部域注入”,必须采用运行时监控手段。</script>
核心思路:劫持 document.cookie 的 setter
我们利用 Object.defineProperty 重定义 document.cookie 的 set 访问器,在每次 Cookie 被赋值时主动捕获调用堆栈。现代浏览器(Chrome、Firefox、Edge)在 Error.stack 中会包含触发该操作的脚本 URL 和行号——而最后一帧(或倒数第二帧)通常指向第三方脚本的执行位置,从而实现来源域识别。
以下为生产可用的监控代码:
<script type="text/javascript">
function monitorCookieOrigin() {
const originalDescriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie');
// 仅当原生 cookie setter 存在时才劫持(兼容性兜底)
if (!originalDescriptor || !originalDescriptor.set) return;
Object.defineProperty(document, 'cookie', {
set: function(value) {
// 捕获调用栈
const stack = new Error().stack;
const lines = stack.split('\n');
// 提取最可能的发起脚本行(跳过内部 native 方法和当前监控函数)
let initiatorLine = lines.find(line =>
line.includes('@') && !line.includes('monitorCookieOrigin') && !line.includes('Object.defineProperty')
) || lines[1] || '';
console.groupCollapsed(`? Cookie write detected`);
console.log('Value:', `"${value}"`);
console.log('Initiator:', initiatorLine.trim());
console.log('Timestamp:', new Date().toISOString());
console.groupEnd();
},
get: originalDescriptor.get,
configurable: true,
enumerable: true
});
}
// 立即启用监控(建议放在 <head> 最早执行)
monitorCookieOrigin();
</script>✅ 典型输出示例(Chrome):
? Cookie write detected Value: "tracking_id=abc123; domain=.domain.a; path=/" Initiator: "at https://domain.b/script.js:42:15" Timestamp: "2024-06-15T08:23:11.456Z"
⚠️ 重要注意事项:
- 仅适用于同步写入:该方法无法捕获 document.cookie 的异步设置(如通过 setTimeout 延迟执行或 Web Worker 中的操作),但绝大多数第三方 SDK 均为同步写入。
- 浏览器差异需适配:Firefox 使用 e.stack(需 try/catch),Chrome/Edge 支持 new Error().stack;上述代码已做兼容处理。
- 不可用于生产环境长期监听:频繁 console.group 可能影响性能;上线前建议替换为自定义日志上报逻辑(如 fetch('/api/audit-cookie', { method: 'POST', body: JSON.stringify(...) }))。
- Same-Origin Policy 限制依然有效:你仍无法读取跨域 Cookie 的原始内容(如 document.cookie 本身受同源策略保护),本方案仅监控“谁在何时写了什么值”,不突破安全边界。
- CSP 影响:若站点启用了严格 Content-Security-Policy(如 unsafe-eval 被禁用),Object.defineProperty 劫持可能失败,需确保 CSP 允许动态属性修改。
总结
通过重定义 document.cookie 的 setter 并解析 Error.stack,开发者可在不依赖服务端日志或浏览器扩展的前提下,精准定位外部域名脚本对当前页面 Cookie 的写入行为。该技术适用于前端安全审计、GDPR 合规检查、第三方 SDK 行为分析等场景。实际部署时,请结合 try/catch 容错、轻量级日志聚合与 CSP 策略验证,确保其稳定性和可维护性。










