On 2024-08-07 16:37, 'Tom Sutcliffe' via lua-l wrote:
> You'd have to also remove package.loaded.os as well, because the top-level `os` is not the only reference to the os table. Safer to never call luaopen_os in the first place, if possible (or if using luaL_newstate(), to switch to lua_newstate() and explicitly luaopen_xyz of only the libs you want). Same thing for the other modules like io.
The way I usually approach this is to compile Lua from source and just
comment out any dangerous functions in the `luaL_Reg` structs in the
l*lib.c files. That generally means the compiler gets rid of the entire
function (since it's static and not referenced anywhere), so even if
someone manages to access stuff outside of the sandbox, the functions
*just aren't there.* (Even if you get to the level of memory corruption
where you can add an offset onto a pointer, you can't point it at a
function that's no longer in the binary. At that point other attacks are
more fruitful.)
That also permits a more fine-grained approach, e.g. keeping the time
functions in `os` while removing all outside interaction.
I also use that opportunity to remove the ability to open files for
writing / updating (adjusting `l_checkmode` in liolib.c), the ability to
load binary / pre-compiled chunks in lbaselib.c / `getMode` (by removing
'b' as an option), and whatever else feels unsafe in the specific
context. (E.g. sometimes xpcall is not ok to keep since it gets around
debug hook timeouts if you just `xpcall( dummy_time_waster,
actual_function )`, but generally it's useful for programming if I don't
need to restrict that.) So there's no hard list of things to exclude /
remove, but looking at all the l*lib.c files isn't that much work.
-- nobody