重新解释这个问题
假设:
>有一个用户可以在文件A中编写任何Ruby代码.
>我编写了一个静态Ruby文件B,它加载文件A并调用A中定义的主例程,还定义了用户可以在A中使用的一些类/方法.
>用户没有对B的r(读)或w(写)权限.
我必须重新定义(无效)或通过在文件B中写入来删除(标准Ruby)方法,以使用户无法访问文件B中写入的源(通过用户可以在文件A中编写的任何代码) )当我运行文件B?
有些像sorcerer,pry这样的库可以提取它可以访问的方法的源代码.在纯Ruby中必须有一些原始命令,这些库依赖于这些命令使它们可以访问源代码.有什么方法可以使这种事情成为可能?
解决方法
首先,为了能够执行Ruby脚本,您必须能够读取它…
但回到这个问题.我知道Sourcify除了在Proc和Method上使用一个名为source_location的方法之外,不使用任何神秘的方法,它给出了文件名和行号是一个方法/ proc定义.我从经验中知道这种方法非常脆弱,需要编写某种解析器,有时只能在合法的情况下工作.所以,如果你在B中重新定义source_location以返回类似/ dev / null,第0行的东西并让Sourcify抛出一个非Ruby源异常,那么Sourcify已经出来了.
从Pry的source开始,似乎Pry使用了相同的source_location方法,因此两只一石二鸟.
现在,所有这些库都有另一种选择,即下拉到C并破解解释器以记录源代码.这几乎完美无瑕.但我们仍然可以通过一种非常简单的方式避免危险.有人可以在A中包含Pry方法源的所有代码.但是,如果不需要C库,则不能包含内联C/C++扩展.因此,解决方案显而易见:重新定义require和require_relative并加载到不工作,或仅允许某些库.这样,你可以阻止C黑客攻击.
在MRI上,除了source_location之外,没有办法(从Ruby代码中)执行此操作.你去吧!
编辑:根据@banister,来自MRI 2.0,内置了一个binding_of_caller方法,可以替换源位置.也是这样.