JavaScript 函数劫持原理与反劫持检测
本文深入解析 JavaScript 中的函数劫持(Function Hijacking)机制,展示如何通过 Hooks 在原函数执行前后注入逻辑。同时介绍利用打印原生代码标识 `[native code]` 进行反劫持检测的方法,以及该技术在防御跨站脚本攻击(XSS)和追踪恶意行为中的实战应用。
什么是函数劫持
函数劫持是指在目标函数实际运行之前,将其“拦截”并替换为自定义的逻辑。当程序调用该函数时,实际上执行的是被篡改后的版本。这与简单的函数重写不同,优秀的劫持操作应当遵循“职业道德”,在完成自定义扩展后,必须将控制权交还给原始函数,确保原功能正常运行。这一机制也是前端框架中常用的 Hook 技术的底层原理之一。
函数劫持的实现步骤
第1步:理解基本劫持逻辑
以最常见的 alert() 为例,我们可以保留其原始引用,并在调用前增加确认弹窗。这种模式可以直观地看到函数执行的拦截过程:
let warn = alert // 保存原始函数的引用
window.alert = (t) => {
if (confirm('How are you?')) {
warn(t) // 调用原始函数
}
}
alert('Help me...!!!') // 此时不会直接弹出,而是先显示确认框
第2步:封装通用劫持函数 (Hook)
为了使劫持更加灵活,可以将其封装为一个通用的辅助函数。核心思路是接收对象、方法名和回调函数。在回调中,我们需要传递原始函数作为参数,以便在执行新逻辑后按需调用它:
const hijack = (obj, method, fun) => {
let orig = obj[method]
// 使用返回的包装函数覆盖原方法
obj[method] = fun(orig)
}
第3步:应用劫持到 confirm() 函数
下面演示如何使用上述 hijack 函数对 confirm() 进行劫持,在其内部加入额外的日志反馈:
hijack(window, 'confirm', (orig) => {
return (text) => {
alert('HELP ME PLZ!!!')
// 执行原始 confirm 逻辑
if (orig.call(this, text)) {
alert('YOU SEEMS FINE AND I AM LEAVING, GOOD BYE!')
} else {
alert('HOLD ON! I AM COMING!!')
}
}
})
完成此设置后,每次触发 confirm 都会执行这一套复杂的自定义流程。
如何检测和反劫持
在开发过程中,判断一个系统原生函数是否被篡改至关重要。最直接的检测方式是在浏览器开发者工具的 Console 中打印该函数。
- 纯净状态:如果输出为
function alert() { [native code] },代表它是未被污染的浏览器原生代码。 - 被劫持状态:如果输出的是一段 JS 代码块(如上文所示的箭头函数),说明该函数已被重写。
因此,通过检查函数体内是否存在 [native code] 标识,可以快速判断当前环境的安全性。
函数劫持在安全防御中的应用
除了功能增强,函数劫持在 Web 安全领域同样扮演着重要角色,尤其是在防御 XSS(跨站脚本攻击)方面。
许多黑客在进行 XSS 测试时,会习惯性地注入 alert() 语句来验证页面是否可被注入脚本。如果我们提前对全局 alert() 进行了劫持,就可以在其中植入追踪代码(例如发送隐藏请求记录攻击者 IP 或 ID),然后再释放给原始的 alert() 执行。这样既能保证正常业务不受影响,又能在不惊动攻击者的情况下捕捉攻击特征。
JS Hijacking 技术与关系
需要区分普通函数劫持与 JavaScript Hijacking 这一特定的 CSRF 漏洞利用技术。
展示了该攻击的典型时序。其核心在于利用存在漏洞的信任网站,在保持登录状态下引导用户访问恶意网站。恶意站点诱导信任站点发起 GET 请求返回敏感数据。
关键实施条件:
- 响应格式:信任网站返回的数据最好是 JSON 数组。如果服务器返回的是 JSON 对象,在某些旧版本引擎中可能会引发类型错误,导致无法赋值;攻击者也可通过在对象前后手动加括号
({...})强行转换为表达式。 - 依赖函数劫持:在攻击链的第五步,通常需要通过重定义数组的原型方法(如
Array.prototype.push)来实现对返回数据的实时劫持和窃取,这再次印证了两者在实现上的密不可分。 - 请求方式:信任网站的敏感接口必须响应
GET请求才能被成功利用。
以上就是关于 JavaScript 函数劫持及其相关安全应用的详细内容,更多关于前端安全防护的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









