JS Hook 攻防案例
2023-09-27 14:21:27 时间
思考题
现有一款浏览器安全插件,会对所有页面的 Performance API 进行 Hook,以降低 JS 获取的时间精度,减少边信道攻击的风险。
该插件会把如下代码注入到页面最开始:
(function() {
const obj = performance
const rawFn = Performance.prototype.now
Performance.prototype.now = function() {
const val = rawFn.apply(obj, arguments)
return ((val * 10) | 0) / 10
}
})()
performance.now() // 11346.9
performance.now() // 12242.1
// 注:原始的 performance.now() 可获得小数点后多位
此外,包括 iframe 等子页面也会被注入该代码。
现在来思考,如何绕过这种防护方案,从而获得原生 performance.now 接口。(同时不损坏业务逻辑)
攻
重写后的逻辑很简单,显然只能从 rawFn.apply
这里入手。
熟悉前端的应该都知道原型链的概念,例如 rawFn.apply === Function.prototype.apply
,前者只是后者的一个引用而已。
所以,攻击者可重写 Function.prototype.apply
函数,然后故意调用一下 performance.now
,触发 rawFn.apply
,于是进入我们的 apply 函数。其中的 this
即 rawFn,就是我们想要的结果!
最后再将 Function.prototype.apply
恢复,不影响后续业务逻辑。
var rawApply = Function.prototype.apply
var rawNow
Function.prototype.apply = function() {
rawNow = this
}
performance.now()
Function.prototype.apply = rawApply
console.log('获得原始接口:', rawNow)
防
作为插件的开发者,又该如何防范这种攻击?
显然,不能使用 rawFn.apply
这种潜在副作用的操作。ES6 提供了 Reflect API,可以更加原子地实现各种操作。
例如 document.createElement('DIV')
,通过 Reflect
可这样调用:
Reflect.apply(document.createElement, document, ['DIV'])
由于 Reflect
下的方法都是静态方法,因此可将其备份到闭包内部的变量里,之后直接使用:
(function() {
const apply = Reflect.apply
const result = apply(document.createElement, document, ['DIV'])
console.log(result)
})()
这样,即使攻击者重写了 Reflect.apply
,我们也不受影响!
进一步,我们可将所有变量都提前备份,完全不依赖全局变量:
(function() {
const document = window.document
const createElement = document.createElement
const apply = Reflect.apply
const result = apply(createElement, document, ['DIV'])
// ...
})()
换成本文开头的案例:
(function() {
const obj = performance
const rawFn = performance.now
const apply = Reflect.apply
Performance.prototype.now = function() {
const val = apply(rawFn, obj, [])
return ((val * 10) | 0) / 10
}
})()
相关文章
- jQuery.Form.js提交表单详解ajaxSubmit()
- Docker最全教程之使用Node.js搭建团队技术文档站(二十三)
- js中取绝对值的2种方法!
- vue.js+koa2项目实战(六)数据库建表
- 渗透测试-xss安全防御之href输出和js输出
- JS leetcode 拥有最多糖果的孩子 题解分析,六一快乐。
- jQuery插件EasyDrag轻松实现JS拖动的效果
- 《WebGL入门指南》——第2章,第2.2节建立Three.js运行环境
- ios(safar/微信)返回不执行js
- [js高手之路]html5 canvas动画教程 - 跟着鼠标移动消失的一堆炫彩小球
- [js高手之路]面向对象+设计模式+继承一步步改造简单的四则运算
- 华为OD机试 - 最短耗时(JS)
- JS冒泡和闭包案例分析
- JS学习第9天——ES6中面向对象(类class、constructor构造函数、类的继承extends、super关键字、面向对象tab栏切换案例)
- JS学习第8天——本地存储(localStorage、sessionStorage、记住用户名案例)
- JS学习第6天——PC端网页特效(元素偏移量offset、元素可视区client、元素滚动scroll、动画函数封装、节流阀、网页轮播图案例、mouseenter与mouseover区别)
- vue2 - 基于Export2Excel.js导出Excel案例(js-xlsx插件二次封装使用)
- js防抖和限流