我想以安全的方式共享内容,而不会将其暴露给恶意代码。假设我有一个
基础插件
local BaseAddon = {}
local secretTable = {someContent = "hidden content"}
local function index(t,k)
if (k == "SECRET") then
return secretTable
end
end
setmetatable(BaseAddon, {
__index = index,
__newindex = function() end,
__metatable = false, -- disallow setmetatable again
})
return BaseAddon -- or a global hook method...
以及一个访问 Base 插件隐藏内容的 Sub 插件
local SubAddon = require("BaseAddon") -- or a global hook method...
SubAddon = SubAddon["SECRET"]
print(SubAddon.somelib) -- returns content
SubAddon = SubAddon["SECRETS"]
print(SubAddon.somelib) -- returns index local 'SubAddon' (a nil value)
但这仍然不安全。我现在可以简单地执行以下操作来发现我的秘密:
function newSetmetatable(table, mt)
mt.__metatable = nil
mt.__index = function(t,k)
print(k)
return t[k]
end
return originalSetmetatable (table, mt)
end
originalSetmetatable = setmetatable
setmetatable = newSetmetatable
有什么方法可以阻止这个或其他解决方案实际共享秘密表吗?
您的原始代码与您在 Lua 中所能得到的一样好。像您在 Lua 中设置的任何类型的安全性都需要用 C 编写,或者在任何不受信任的代码运行之前运行。
您可以在没有
setmetatable
的环境中加载插件。然而,这可能会使编写插件变得尴尬。
lua-sandbox是一个促进这种沙箱的项目。它使用 setfenv 和 其阻塞函数包括 setmetatable:
不安全的包/函数列表:
{set|get}元表:可用于修改全局对象(字符串、整数)的元表