You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何阻止用户通过属性调用访问模块内部导入的其他模块

实现方案

一、隐藏模块内部导入的os

先解决禁止用户直接访问my_module.os的问题,可通过以下三种方式组合实现:

  • 导入时使用私有别名:把import os改为import os as _os,Python社区默认单下划线开头的成员为模块私有,不会被from my_module import *默认导入,普通用户也不会主动访问这类私有成员。
  • 自定义模块级__getattr__拦截访问:在你的模块文件末尾添加以下代码,主动拦截对os属性的访问:
def __getattr__(name):
    if name == "os":
        raise AttributeError("当前模块不允许直接访问os依赖")
    raise AttributeError(f"模块没有名为{name}的属性")
  • 显式声明__all__:只把你允许对外暴露的成员写入__all__列表,进一步避免未授权内容被导入。

二、用AST配合命名空间限制exec的可用模块

这个需求可以实现,核心方案是AST语法检测+自定义exec命名空间组合使用,具体步骤如下:

  1. 先通过AST遍历检测用户代码的违规操作
    把用户传入exec的代码解析为AST树后,遍历所有节点拦截以下违规场景:
  • 检测Import、ImportFrom节点:检查导入的模块名是否在你预设的白名单内,不在则直接拒绝执行。
  • 检测Attribute节点:拦截所有访问你模块私有成员的操作,比如my_module.os这类属性访问。
  • 检测Call节点:禁止调用__import__、getattr、importlib.import_module这类容易绕过限制的反射函数,或者对这类调用的参数做严格的字面量校验。
    注意:仅靠AST无法覆盖字符串拼接构造的动态导入场景,必须配合命名空间限制使用
  1. 给exec传入限制级命名空间(比AST检测更高效的兜底方案)
    执行exec的时候手动指定globals和locals参数,只把你允许用户使用的模块、函数放到命名空间里,示例代码如下:
# 只保留允许用户使用的对象
allowed_globals = {
    "math": math,
    "my_module": my_module,
    # 仅保留允许的内置函数,删除__import__、getattr等危险接口
    "__builtins__": {k: v for k, v in __builtins__.__dict__.items() if k in ["print", "int", "str", "sum"]}
}
exec(user_code, allowed_globals, {})

这种场景下就算用户写出import os的代码,也会因为命名空间里没有__import__函数执行失败,就算成功导入也没法把os放到可用的命名空间里。

三、注意事项

不存在100%安全的限制方案:Python的动态性决定了总有极端方法可以绕过限制,比如用字符串拼接构造反射参数、利用异常栈信息获取私有成员等,如果你需要执行完全不可信的用户代码,建议使用专用沙箱环境而不是单纯靠AST+exec限制。
普通业务场景下,私有别名+自定义__getattr__+自定义exec命名空间的组合已经足够覆盖绝大多数需求,可以挡住所有非刻意的违规调用。

内容的提问来源于stack exchange,提问作者Gleb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 03:06:05