如何防止setmetatable被覆盖

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

我想以安全的方式共享内容,而不会将其暴露给恶意代码。假设我有一个

基础插件

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

有什么方法可以阻止这个或其他解决方案实际共享秘密表吗?

security lua overriding lua-table metatable
2个回答
0
投票

您的原始代码与您在 Lua 中所能得到的一样好。像您在 Lua 中设置的任何类型的安全性都需要用 C 编写,或者在任何不受信任的代码运行之前运行。


0
投票

您可以在没有

setmetatable
的环境中加载插件。然而,这可能会使编写插件变得尴尬。

参见5.1中的setfenv这篇文章在5.2+中编写它。

lua-sandbox是一个促进这种沙箱的项目。它使用 setfenv 和 其阻塞函数包括 setmetatable:

不安全的包/函数列表:

{set|get}元表:可用于修改全局对象(字符串、整数)的元表

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