如何防止 setmetatable 被覆盖

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

Base addon

local BaseAddon = {}
local secretTable = {someContent = "隐藏的内容"}

local function index(t,k)
  if (k == "SECRET") then
    return secretTable
  end
end

setmetatable(BaseAddon, {
  __index = index,
  __newindex = function() end,
  __metatable  = false, -- 禁止再次设置metatable
})

return BaseAddon -- 或全局钩子方法...

和一个访问 Base addon 的隐藏内容的 Sub addon

local SubAddon = require("BaseAddon") -- 或全局钩子方法...

SubAddon = SubAddon["SECRET"]
print(SubAddon.somelib) -- 返回内容

SubAddon = SubAddon["SECRETS"]
print(SubAddon.somelib) -- 返回索引值 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

有没有办法防止这种情况或另一种实际共享秘密表的解决方案?

点赞
用户7509065
用户7509065

你的原始代码在Lua中已经是最好的了。任何类似于你在Lua中设置的安全性,需要在C语言中编写,或者在运行任何不受信任的代码之前运行。

2020-11-22 00:49:29