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

如何在PySide/PyQt绑定的Python沙箱中阻止文件读写?

解决方案:在Qt绑定环境下实现沙箱文件读写限制

可行方案汇总

方案1:Qt全局拦截与类重写

Qt的文件操作类(如QFile、QFileDialog)可通过重写或事件过滤拦截:

  • 重写QFile的open方法,直接返回失败并抛出权限错误;
  • 安装全局事件过滤器,拦截文件对话框的显示请求,直接拒绝;
  • 代码示例(PySide6):
from PySide6.QtCore import QObject, QEvent, QFile, QIODevice
from PySide6.QtWidgets import QApplication, QFileDialog

class FileBlocker(QObject):
    def eventFilter(self, obj, event):
        if isinstance(obj, QFileDialog) and event.type() == QEvent.Show:
            obj.reject()
            return True
        return super().eventFilter(obj, event)

# 安装全局过滤器
app = QApplication([])
blocker = FileBlocker()
app.installEventFilter(blocker)

# 重写QFile类
class RestrictedQFile(QFile):
    def open(self, mode):
        self.setErrorString("沙箱内禁止文件操作")
        return False

# 替换全局QFile实现
import PySide6.QtCore
PySide6.QtCore.QFile = RestrictedQFile

方案2:C++层面Hook Qt文件API

若Python重写存在绕过风险,可通过C++插件或动态注入拦截Qt底层文件操作:

  • 编写Qt插件,替换QFile::open等虚函数的实现;
  • 利用系统级动态链接注入(如Windows DLL注入、Linux LD_PRELOAD)拦截系统文件调用;
  • C++示例片段(Hook QFile::open):
#include <QFile>
#include <QIODevice>

typedef bool (*OriginalOpen)(QFile*, QIODevice::OpenMode);
OriginalOpen originalOpen = nullptr;

bool hookedOpen(QFile* file, QIODevice::OpenMode mode) {
    file->setErrorString("沙箱内禁止文件操作");
    return false;
}

void initHook() {
    auto vtable = *reinterpret_cast<void***>(new QFile);
    // 需根据Qt版本调整虚函数索引
    originalOpen = reinterpret_cast<OriginalOpen>(vtable[27]);
    vtable[27] = reinterpret_cast<void*>(hookedOpen);
    delete new QFile;
}

方案3:增强RestrictedPython限制

结合现有RestrictedPython,扩展其规则覆盖Qt文件操作:

  • 包装Qt文件类,拦截核心方法调用;
  • 构建安全全局变量,替换危险API;
  • 代码示例:
from RestrictedPython import compile_restricted, safe_globals

def restricted_qfile_open(self, mode):
    raise PermissionError("沙箱内禁止文件操作")

# 替换安全全局变量中的QFile
safe_globals['QFile'] = type('RestrictedQFile', (safe_globals.get('QFile', object),), {
    'open': restricted_qfile_open
})

# 编译执行脚本
with open("script.py") as script:
    code = compile_restricted(script.read(), '<script>', 'exec')
    exec(code, safe_globals)

方案4:利用Qt系统沙箱机制(Qt 5.10+)

Qt提供的QSandbox类可对接系统级沙箱(如Windows AppContainer、Linux Flatpak):

  • 配置文件系统访问权限为完全禁止;
  • 注意:依赖系统平台支持,需适配不同系统策略;
  • 代码示例:
from PySide6.QtCore import QSandbox

sandbox = QSandbox()
sandbox.setFileSystemAccess(QSandbox.NoAccess)
sandbox.start()

关键注意事项

  • 需覆盖所有Qt文件操作路径,包括QTextStream、QDataStream等间接调用;
  • 动态Hook需适配不同Qt版本的函数偏移,可借助工具分析虚函数表;
  • RestrictedPython包装要覆盖所有可能被脚本调用的Qt文件相关类,避免绕过。

内容的提问来源于stack exchange,提问作者Dante S.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:03:30