我的问题有两个方面。 首先,沙箱模型如何工作,如何影响用户脚本,从网页和用户脚本的 Angular 可以访问/看到的内容,以及如果使用其他沙箱模型也会影响页面,从而能够注意到您的脚本已注入(inject)到页面(或没有)。 第二个,如何将脚本注入(inject)到页面中,并且页面可以检测到它?
第一
据我所知,当您使用@grant none时,沙箱被禁用,您将可以访问该网页及其javascript。如果您对javascript和/或DOM进行了任何更改,则该页面可能会检测到它。
我的理解是,如果您使用@grant unsafeWindow,您的脚本将被隔离在其自己的js上下文中,您对window所做的任何操作都不会被网页看到,但是您可以通过unsafeWindow访问该网页和javascript。您将可以定期访问DOM,例如document返回常规页面文档,而不需要您说unsafeWindow.document。显然,您对DOM或页面js上下文所做的任何更改(例如unsafeWindow.foo = 'bar';)仍然可以检测到。之所以成为unsafe的原因不是因为是否被检测到,而是因为您有可能在此模式下向不可信页面授予特权GM_*函数的访问权限(在常规模式下不授予该权限,这意味着任何功能的@grant GM_*将隔离js上下文,除非您@grant unsafeWindow,否则您将无法访问页面的js上下文。
第二
如何将脚本注入(inject)页面?网页是否可能注意到用户脚本注入(inject)(假设用户脚本修改了页面上的NOTHING)。
例如,如果脚本是使用script标记注入(inject)的,那么我认为该页面可能会注意到脚本注入(inject),甚至可以查看其代码吗?
沙盒模型在这种情况发生过程中是否具有任何作用,并使它“更安全”而不被看到?例如,如果使用@grant unsafeWindow隔离了js上下文,则网页上的js甚至看不到任何用户脚本加载事件,这使得@grant unsafeWindow从根本上更加安全,除非您当然要修改DOM或unsafeWindow。
我还假设没有泄漏特殊功能,对象,属性等(例如GM_info到网页,这会背叛tampermonkey的存在?)。既不在@grant none模式下也不在@grant unsafeWindow模式下(前提是您没有向页面泄漏任何内容)
这让我感觉到,只要不进行任何修改(特别是不要将特权的unsafeWindow函数暴露给unsafeWindow),就不会被检测到GM_*实际上更安全(因为js上下文是隔离的)。例如,如果在@grant none模式下使用eventListener,则可能会检测到它,但如果在@grant unsafeWindow模式下使用它,则可能由于隔离而无法检测到它?此外,如果某个页面有可能检测到用户脚本加载(我不知道这是否可能实现),那么它将不知道js上下文是否被隔离。
简要说明一下,如果您不背叛页面,那么页面可以检测到用户脚本或tampermonkey的存在吗?
我的上述任何想法在任何领域都是不正确的吗?如果是,那么它实际上是如何工作的?
更新
一些需要澄清的信息:
用户脚本仅从页面被动地读取信息(可能使用MutationObserver)。它不会以任何方式改变任何内容,不使用任何js库(既不在用户脚本中也不从网页中使用),没有ajax调用,没有脚本节点,绝对没有单击等。该脚本可以从JS vars中读取一些信息页面(假设那些变量和函数没有被诱杀式诱骗),以及使用WebSocket(内部服务)。也使用IIFE。因此,主要的问题是,篡改猴子本身(如果运行页面脚本)本身是否可检测?
在这个答案中:https://stackoverflow.com/a/8548311
我可以排除1、4、5、6和7;也可能是2和3,但我不知道坦佩罗尼本身是否会影响其中的任何一个
最佳答案
浏览器和Greasemonkey/Tampermonkey/Violentmonkey(大部分)已改进了注入(inject),作用域和沙盒的方式。不会使用普通的<script>标签注入(inject)用户脚本(尽管您的脚本可能需要在某些情况下创建此类标签)。
实际上,如今是there's almost no need to use an IIFE。
但是,除了previously linked question中的检测方法之外:
@grant none模式下,如果您将自己复制到@require范围的库进行window,则,页面可以看到它。大多数库都不会这样做,但是这样做的是 jQuery 。 require模式下的@grant none全局库,页面无法检测到。 Allow communication with cooperate pages设置为默认值。)
关于javascript - 网页可以检测到篡改用户脚本吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56821042/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我有一个在Linux服务器上运行的ruby脚本。它不使用rails或任何东西。它基本上是一个命令行ruby脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI