Skip to content

How do I protect Lua Globals from write access? #185

Open

Description

@volundmush

I'm working with some code, trying to setup a sandbox for running untrusted user code on my server. Currently one of my protections is against endless loops - this is achieved by using Lua's debug.sethook() to call a sanity check every x instructions. unfortunately, sethook() won't accept a POBJECT in place of the function it wants, and this means that I need to set the Python code being called somewhere on the globals. But if a user were to replace this variable with function() end, then my safety check is bypassed.

I've been trying to create some kind of proxy object for the globals table that will protect its entries, but haven't had much luck.

How does one go about this in Lupa?

Activity

  1. scoder commented on Jun 8, 2021

    @scoder
    Owner

    I'm not sure if there is a way to do this, currently. The security mechanisms are meant to protect the Python side, not the Lua side.

    Assuming that Lua doesn't provide a way to control the runtime itself, my guess is that the only safe way to do this is in a separate process that you can kill if it times out.

    Did you try using a closure, though? Something like this (untested):

    function call_py(py_func) return function () py_func() end end
  2. volundmush commented on Jun 8, 2021

    @volundmush
    Author

    Yeah. I tried the separate thread approach, but it introduces many issues with my game's internal api.

    Over on freenode's #lua channel, I heard that the way to do this would be to replace the globals up value with a custom object with a metatable.

    How hard would adding some kind of get/set filtering on the globals be, similar to the one used on pyobjects?

  3. guidanoli commented on Jun 13, 2021

    @guidanoli
    Contributor

    The following Lua code should do the trick.
    The __newindex is triggered every new entry.
    The __metatable prevents others from accessing the metatable or overriding it.

    setmetatable(_G, {__newindex = function() error("can't set global values") end, __metatable = false})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions