security - 使用 LuaJIT 编写脚本并选择性地沙盒化 FFI

标签 security lua sandbox ffi luajit

在尝试并见证了将 Lua 和 LuaJIT 集成到我的游戏引擎中令人难以置信的轻松之后,我确信这就是我想要使用的脚本语言。我想将它用于我的 AI、单位描述、 map 触发器等。 (尽可能真的)。这个问题不仅适用于游戏开发,我可以想象创建一个可以加载外部脚本的脚本编辑器或窗口管理器(例如:带有 python 和包控制的崇高文本)

但现在我有一个难题:我真的很欣赏 的易用性。 LuaJIT FFI 提供绑定(bind)到我的引擎,但我 不想向 map 作者提供 FFI 的自由统治 例如。通过 FFI(当 JITted 时)进行 lua-to-c 调用的惊人速度也是我真正想要的。

所以理想情况下,我会编写自己的包装 Lua 文件,使用 FFI 绑定(bind)到我的引擎,并导出一个不错的模块供 map 作者和模组制作者使用。我的替代方法是编写一个 Vanilla lua 模块,这是可能的,但更麻烦和更慢。

编译 luajit 时我无法禁用 FFI,因为显然我想自己使用它,但我不知道如何在每个脚本或每个模块的基础上限制 FFI。显然,FFI 需要在我加载模块的 lua_State 中处于事件状态(之后我无法开始加载用户修改的脚本)。那我该怎么办?甚至可能吗?

编辑 :在我看来,理想的工作流程是:

  • 开启lua状态
  • 加载所有模块 (luaL_openlibs()),FFI 也被预加载
  • 加载我的 .lua 模块,这些模块使用 FFI(这是引擎绑定(bind),它们是受信任的文件,因此可以使用 FFI)
  • 禁用选择 native 模块和功能:os、ffi、...(这是缺少的步骤)
  • 执行用户提供的脚本(这些是不受信任的,我不希望他们访问 FFI)
  • 可选 : 寻找一种重新加载 lua 模块以实现快速编辑周期的方法,这将涉及重新启用 FFI 和其他模块。 ( 也不知道怎么做 )

  • 注意 :我知道这仍然不是一个完美的(甚至是好的沙盒),正如 Mike Pall 在他的一些邮件中已经指出的那样,但我仍然不想让 map 作者访问 FFI。

    最佳答案

    也许我不明白这个问题,但如果你使用 a normal Lua sandbox无法访问 FFI,有什么问题?

    例如:

    ffi = require "ffi"
    
    ffi.cdef([[int printf(const char *fmt, ...);]])
    
    function say_hello()
      ffi.C.printf("%s", "hello, ");
    end
    
    my_user_script = [[
    say_hello()
    ffi.C.printf("%s\n", "world")
    ]]
    
    f = loadstring(my_user_script)
    
    print("=== without sandbox ===")
    print(pcall(f))
    
    print("=== with sandbox ===")
    setfenv(f,{say_hello = say_hello})
    print(pcall(f))
    

    这应该输出:
    === without sandbox ===
    hello, world
    true
    === with sandbox ===
    hello, false    [string "say_hello()..."]:2: attempt to index global 'ffi' (a nil value)
    

    请注意,您还需要注意不要将 FFI cdata 泄漏到沙箱中。有a paragraph about this in the LuaJIT documentation .

    关于security - 使用 LuaJIT 编写脚本并选择性地沙盒化 FFI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18376966/

    相关文章:

    Lua,关于__gc设置顺序的问题

    传递给 create_function 的 PHP 沙箱/清理代码

    database - 双重哈希结合加盐是一种有效的密码存储技术吗?

    c++ - 静态虚函数

    security - 引用 header 中的 CDN 和个人身份信息

    if-statement - Lua 'end' 预计关闭 'if'

    python - PyInstaller 生成的可执行文件在 MacOS X 上的代码签名不被接受

    macos - QLPreviewView 无法在沙盒中显示快速预览

    java - 授予单一类权限

    php - 限制对Docker容器内容的访问