1 回答
TA贡献1794条经验 获得超8个赞
跳出“盒子”思考
由于“似乎”没有办法以“好”的方式做到这一点,因此人们总是可以运用微小的创造力来实现特定的结果。
简单回顾一下:
该要求是有办法从那里的请求时识别
这可以在每次
Worker
调用时手动实现,也可以自动实现任何安全问题似乎都在别处处理
Worker
在调用时更改URL 可能有助于自动处理
可行的解决方案
这是一个可用于“劫持”某些类调用或方法的包装器:
const hijack = function(driver,victim,jacker)
{
if(((typeof driver)=='string')&&!victim){return this.plan[driver]}; // recap
if(victim in this.plan){return}; // only jack once? .. less cruel
this.plan[victim]={victim:driver[victim],jacker:jacker}; // plan the heist
let con = {enumerable:false,configurable:false,writable:false,value:function()
{
let car=hijack((this.mask||this.name||this.constructor.name)); let m=this.mask;
let arg=car.jacker.apply(null,arguments); if(!Array.isArray(arg)){arg=[arg]};
if(!m){return new (Function.prototype.bind.apply(car.victim,[null].concat(arg)))()}
else{return car.victim.apply(this,arg)};
}};
try{con.value.prototype = Object.create(driver[victim].prototype)} // blend in
catch(oops){Object.defineProperty(driver,'mask',{value:victim});}; // recover
Object.defineProperty(driver,victim,con);
}.bind({plan:{}});
... 钉子遇上锤子
这个怎么运作
它接受 3 个参数:
driver
~ 包含目标函数/方法的对象victim
~ 将被拦截的函数/方法的名称jacker
~ 一个回调函数 - 用于中继/更改参数原方法复制到可以使用的地方或者后续调用
回调强加(废弃)原始的,并且可以在调用者和被调用者之间传递不变的参数(与原始的完全一样),但现在你可以控制它是如何发生的(如果有的话)以及准确地传递什么;要么有一些简单的条件,要么有一些精心设计的计划(又名“邪恶计划”)
为了简单起见,这段代码(上面)只允许每个 1 次拦截
victim
,但这可以扩展为多次拦截;通过“链中继”(回调数组)或“事件调度程序 + 事件侦听器组合”。
如何使用
具体问题:
hijack(window,'Worker',function(arg){return `${arg}?worker=true`});
为了解决评论中的安全问题,api-key可能很有用;因此,如果将 somestring
传递给当前会话(或客户端)独有的正在运行的实例(浏览器或服务器),则就足够了,例如:
hijack(window,'Worker',function(arg){return `${arg}?worker=${window.ApiKey}`});
.. whereApiKey
被全局定义为 a string
,但它也可以是函数调用的结果 - 它从 cookie 中获取它,或以任何方式获取。
有用的工具
这也可用于增强安全性。如果您担心来自devtools或更糟的XHR请求:eval() - 那么您可以使用它来全局拦截这些调用/调用。hijack
例如:
hijack(URL,'createObjectURL',function(arg){console.log(arg); return `whatever`});
如果您打算将其用作安全工具,那么它需要一些带有“调用堆栈回溯”的 TLC、一个“突变观察者”……和一小撮(暗)物质(:
免责声明
在此练习中没有人受伤.. 受害者结果还好.. 自行决定使用
添加回答
举报