前文
最近又碰到了一个比较有意思的问题
个人认为这篇文章比较有助于大家理解
由于涉及到一些原理的概念
说起来如果难吧,又不难
如果说简单吧,就还有点难
开始
如果我们使用var来声明变量,这个时候会挂载到window,输入变量名或者window.变量名都是没问题的
但是如果声明let或者const,变量并不在window作用域上,只能使用water进行引用
那我们在油猴脚本里如果是沙盒模式,就没办法用unsafeWindow来引用变量了
那我们该怎么搞呢?
我第一反应是在unsafeWindow下写一个函数并且执行
unsafeWindow.fuck_let=function(){
console.log(water)
}
经过测试是可以正确输出的
但是很快这种猜想就被推翻了
因为即使输出
console.log(water)
依然可以打印出来内容
这是为什么呢?
我们在油猴脚本里打个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,全局变量泄露
这个时候就出现了不安全因素!
我们脚本的变量跟网页出现了共享读写!
所以大家要避免这种操作
结语
撒花花~