【问题标题】:PHP - How to check if request is for JS workerPHP - 如何检查请求是否针对 JS 工作者
【发布时间】:2020-02-15 23:01:45
【问题描述】:

在就 referrer-policy 和谷歌搜索、DuckDucking 和 StackOverlow-searching 咨询 MDN 之后,也许您可​​以帮助我解决这个相当简单(但很虚幻)的问题?

工艺流程

  1. 浏览器向服务器发出请求
  2. 根据 HTTP_REFERER 标头,服务器决定响应

但是为什么呢? (你问)

这是一组精心设计的安全检查的一部分,在这种情况下决定客户端是否有权访问请求的文件FUBU(由我们为我们)。

如果 referer 丢失,这将不起作用,但是当 JavaScript 向指定的工作人员发出请求时 - referer(请求头)确实丢失了。

我已经尝试过 - 并且失败了

  • 为每个请求设置Referrer-Policy: same-origin
  • 设置适当的 CORS 标头 Access-Control-Allow-Headers: x-requested-with - 以响应每个请求。

问题

如何确定是否对 JS 工作文件发出了请求,或者只是强制 HTTP 机制按其应有的方式运行?

【问题讨论】:

  • 你不能。您不能信任客户,它也可能提供虚假的推荐人。
  • 你不应该依赖HTTP_REFERER,就像"In short, it cannot really be trusted"
  • 也许您正在寻找CORS
  • 首先,好问题!其次,如何附加类似worker.js?from=worker
  • 我刚刚有了一个最疯狂的想法——如何通过为每个后续实例创建一个包装器并在末尾附加一些安全密钥来劫持Worker 构造函数——从服务器提供? ...如果我知道如何创建一个 Worker 包装器 .. 我需要研究这个

标签: javascript php http-headers web-worker


【解决方案1】:

跳出“框框”思考

既然“似乎”没有办法以“好”的方式做到这一点,人们总是可以运用一点创造力来实现特定的结果。

回顾一下:

  • 要求是有一种方法来识别从哪里发出请求
  • 这可以通过 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 个参数:
    1. driver ~ 包含目标函数/方法的对象
    2. victim ~ 将被拦截的函数/方法的名称
    3. jacker ~ 一个回调函数 - 用于中继/更改参数
  • 将原始方法复制到可以使用或后续调用的位置
  • 回调强制(取消)原始参数,并且可以在调用者和被调用者之间传递不变的参数(与原始参数完全相同),但现在您可以控制它如何发生(如果有的话)以及准确传递什么;要么有一些简单的条件,要么有一些复杂的计划(又名“邪恶计划”)
  • 为简单起见,这段代码(上图)只允许每个victim 进行1 次拦截,但这可以扩展为多次拦截;通过“chain-relay”(回调数组)或“event-dispatcher + event-listener combo(s)”。

如何使用

具体问题:

hijack(window,'Worker',function(arg){return `${arg}?worker=true`});

为了解决 cmets 中的安全问题,api-key 可能很有用;因此,如果将一些 string 传递给当前会话(或客户端)唯一的正在运行的实例(浏览器或服务器),它就足够了,例如:

hijack(window,'Worker',function(arg){return `${arg}?worker=${window.ApiKey}`});

.. 其中ApiKey 被全局定义为string,但它也可以是函数调用的结果——从cookie 中获取它,或者其他。

有用的工具

这也可用于增强安全性。如果您担心 devtools 发出的 XHR 请求甚至更糟:eval( ) - 那么你可以使用这个hijack 来全局拦截这些调用/调用。

例如:

hijack(URL,'createObjectURL',function(arg){console.log(arg); return `whatever`});

如果您打算将其用作安全工具,那么它需要一些 TLC 以及一些“调用堆栈回溯”、“突变观察器”......以及一些(暗)物质(:

免责声明
在此练习中没有人受伤 .. 受害者没事 .. 自行决定使用 p>

【讨论】:

  • 有效!天哪,你救了我。我的老板认为这是“黑客”,但也补充说它可能很有用,因为它的应用程序可以解决一般前端黑客的一些问题.....使用黑客来防止黑客,你每天都会学到新东西.现在,改变措辞嘿嘿嘿 :D 谢谢你亲爱的陌生人。
  • @mika - 我已经发布了一个“前端”安全问答here - 与此答案相关。希望对你有帮助
  • 谢谢!我已经阅读了你的文章,我会努力分享我所学到的。
猜你喜欢
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
  • 2019-08-31
  • 2015-09-16
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多