李恒道 发表于 2022-11-27 14:59:49

【油猴脚本开发指南】关于脚本与网页作用域的引申

# 前文
最近又碰到了一个比较有意思的问题
个人认为这篇文章比较有助于大家理解
由于涉及到一些原理的概念
说起来如果难吧,又不难
如果说简单吧,就还有点难
# 开始
如果我们使用var来声明变量,这个时候会挂载到window,输入变量名或者window.变量名都是没问题的
![图片.png](data/attachment/forum/202211/27/145046xula4kaff36g3ald.png)
但是如果声明let或者const,变量并不在window作用域上,只能使用water进行引用
![图片.png](data/attachment/forum/202211/27/145133r7c7c7qsp6qpcoff.png)
那我们在油猴脚本里如果是沙盒模式,就没办法用unsafeWindow来引用变量了
那我们该怎么搞呢?
我第一反应是在unsafeWindow下写一个函数并且执行
```javascript
unsafeWindow.fuck_let=function(){
    console.log(water)
}
```
经过测试是可以正确输出的
![图片.png](data/attachment/forum/202211/27/145443jus3y97iy5hh9ub9.png)
但是很快这种猜想就被推翻了
因为即使输出
console.log(water)
依然可以打印出来内容
这是为什么呢?
![图片.png](data/attachment/forum/202211/27/145515isunnjykzkk7ezjk.png)
我们在油猴脚本里打个debugger
然后格式化看上方代码
具体我们之前也分析过
大概就是往window赋值一个函数
然后调用
函数内部通过with设置一下this,this内包含一个window
所以产生了一个proxy window
最后才执行到我们的函数
也就是理一下作用域
可以得出结论是

window
proxy window(我们with中的this所产生的属性)
函数
我们的代码

如果我们试图console.log(water)
那就会先找到函数
函数里面没有
再找到proxy window
proxy window也不存在这个属性
然后就找到了网页内的window上的这个属性了
所以说我们脚本可以直接通过
console.log(water)
找到网页中定义的let或者const变量
# 引申
如果我们直接在油猴内书写
global_test=888
也会直接被设置到网页中
因为严格意义上来讲proxy window只是油猴创造的一个作用域
并不属于网页的最初涉及
这时候global_test没有声明变量操作符let const var等
根据js涉及会直接逃逸到最顶层
也就是网页的window上
该情况的名称叫做Global variable leak,全局变量泄露
这个时候就出现了不安全因素!
我们脚本的变量跟网页出现了共享读写!
所以大家要避免这种操作
# 结语
撒花花~

极品小猫 发表于 2022-11-28 12:12:41

GG录个视频教程,绝对流量爆炸,很多小白需要这个{:4_93:}

李恒道 发表于 2022-11-28 14:12:29

极品小猫 发表于 2022-11-28 12:12
GG录个视频教程,绝对流量爆炸,很多小白需要这个

我为啥怀疑小猫偷偷写了自动回复脚本
页: [1]
查看完整版本: 【油猴脚本开发指南】关于脚本与网页作用域的引申