有没有办法以编程方式限制python对存储的访问?

如何解决有没有办法以编程方式限制python对存储的访问?

所以我有一些未经验证的脚本,它们是动态生成的,需要运行。所以我不得不限制对模块的访问,在我的例子中是 ioosshutil 等......

在这是我尝试过的东西

from types import ModuleType

def generate_empty_globals():
    return ModuleType("__main__").__dict__


module_locker = """
import os,sys,io
def empty_module(module):
    for x in dir(module):
        setattr(module,x,None)

empty_module(os)
empty_module(sys)
empty_module(io)
"""
my_module = generate_empty_globals()

code = """ ... """
exec(module_locker,my_module)
exec(code,my_module)

现在在上面的方法中,我已经导入模块并将其中的每个函数变量设置为 None,这样如果未知代码运行并导入库,则不会重新导入库,因为库已经导入,这提供了良好的安全级别,但同时你也有这样的代码

import os 
import importlib

importlib.reload(os)

因此允许他们再次访问模块。所以我想我可以通过阻止 importlib 本身的重新加载方法来阻止它们,但不幸的是,一些代码依赖于这种重新加载能力。现在我脑子里有了一个新想法,基本上就是用ast修改代码结构,去掉那些import语句,但是我不知道怎么做,那么有没有不依赖平台的方法呢?具体方法

编辑

只是一种限制模块访问的方法(仅限)。对于模块的允许,我将使用一个特殊的模块或说 api。

解决方法

首先让我说我认为您应该真正考虑替代方案,例如使用子进程作为更受限制的用户运行。如果您的双手被束缚并且由于某种原因被迫以这种方式实现它,您可能需要查看 importlib 钩子(在您记录声明使用导入钩子解决问题是一个坏主意之后)。

来自PEP 302 - New Import Hooks

导入钩子有两种类型:元钩子和路径钩子。在导入处理开始时调用元钩子,在任何其他导入处理之前(这样元钩子可以覆盖 sys.path 处理、冻结模块,甚至内置模块)。要注册元钩子,只需将 finder 对象添加到 sys.meta_path(已注册元钩子列表)。

importlib.abc.MetaPathFinder

代表元路径查找器的抽象基类。为了 兼容性,这是 Finder 的子类。

3.3 版中的新功能。

find_spec(fullname,path,target=None)

用于查找指定模块规范的抽象方法。如果 这是顶级导入,路径将为无。否则,这是一个 搜索子包或模块,路径将是 路径 来自父包。如果找不到规范,则返回 None 。传入时,target 是一个模块对象,finder 可能用于对返回的规范进行更有根据的猜测。 importlib.util.spec_from_loader() 可能有助于实现 具体的 MetaPathFinders。

3.4 版中的新功能。

find_module(fullname,path)

为指定模块查找加载器的旧方法。如果这是顶级导入,路径将为无。否则,这是对子包或模块的搜索,路径将是父包中 path 的值。如果找不到加载器,则返回 None。

如果定义了 find_spec(),则提供向后兼容的功能。

在 3.4 版更改:调用时返回 None 而不是引发 未实现错误。可以使用 find_spec() 来提供功能。

自 3.4 版起已弃用:改用 find_spec()。

invalidate_caches()

一个可选的方法,当被调用时,应该 使查找器使用的任何内部缓存无效。使用人 importlib.invalidate_caches() 当所有缓存失效时 sys.meta_path 上的发现者。

在 3.4 版更改:调用时返回 None 而不是 未实施。

只是稍微玩了一下,我就能够制作一个导入钩子来检查请求的模块是否在批准的模块列表中。如果是,则使用默认导入器导入模块。如果不是,则会引发错误。

通过这样的解决方案,我可以想到两个主要问题(肯定还有更多)。首先,一个顶级模块可以导入几十个其他模块。其次,如果您需要允许脚本导入 sys 或 importlib,他们可以轻松找到绕过导入限制的方法。

import sys
import importlib

class MyImporter():
    original_importers = sys.meta_path
    approved = ['os']
    
    @classmethod
    def find_spec(cls,fullname,target=None):
        if fullname not in cls.approved:
            raise RuntimeError('Permission for module {} not approved'.format(fullname))
        for importer in cls.original_importers:
            spec =  importer.find_spec(fullname,target)
            if spec is not None:
                return spec
        return None

if __name__ == '__main__':
    importlib.abc.MetaPathFinder.register(MyImporter)
    sys.meta_path = [MyImporter]
    import os
    import argparse # fails because argparse is not in approved modules

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?