如何实现 "沙盒 "功能?

问题描述 投票:0回答:1

目前,我正在用Lua写一个沙盒。到目前为止,它还在工作,但我可以使用 getfenv 来获取沙盒外的作用域。对于我的沙盒,我用受信任的函数和库填充了一个空表。然而,对于诸如 print,你可以使用 getfenv 来获取该作用域中的全局变量。比如说。

asd = "asd"
assert(pcall(assert(load([[
print(getfenv(print).asd) -- "asd"
]], nil, "t", {print = print, getfenv = getfenv}))))

这显然可以让 "对手 "绕过沙盒。

function lua sandbox
1个回答
0
投票

你需要为这个函数写一个包装器 getfenv 防止泄露未沙盒的环境,如 MediaWiki的Scribunto扩展 的作用。

    local function my_getfenv( func )
        local env
        if type( func ) == 'number' then
            if func <= 0 then
                error( "'getfenv' cannot get the global environment" )
            end
            env = old_getfenv( func + 1 )
        elseif type( func ) == 'function' then
            env = old_getfenv( func )
        else
            error( "'getfenv' cannot get the global environment" )
        end

        if protectedEnvironments[env] then
            return nil
        else
            return env
        end
    end

它的要点是检查返回的环境 如果是受保护的环境(例如: _G),则拒绝返回它。唯一的诀窍是处理参数,因为参数的类型不同,意义也不同,而且它对调用栈中的额外函数很敏感。

© www.soinside.com 2019 - 2024. All rights reserved.