TL;DR is that most Lua engines seem to offer pretty weak support for sandboxing, unfortunately. Gopher-lua, that Supershields is using, makes it hard to adopt a whitelist-approach where you disable more or less everything and then enable just the functionality you want. Blacklisting (where you specify everything you want to disable) is fairly simple though, but not as secure of course.
For Supershields I have used a combination of blacklisting and running the scripts on serverless instances (AWS Lambda), which limits the impact of a breach.
Looking at this docs page[1], it doesn't look like the execution environment gets reset completely between each request. Do you partition free/paying users or public/private repos? It seems like an attacker could gain a foothold for longer than just their request with malicious code.
That's a good observation. I don't currently do any partitioning and I think I have to read up a bit on exactly how Lambda executes Go functions. If they keep the program state between executions there are probably some cleanup I should be doing. If not, I think I'm safe as script code and everything related to a new script execution gets sent as parameters in the Lambda invocation.
TL;DR is that most Lua engines seem to offer pretty weak support for sandboxing, unfortunately. Gopher-lua, that Supershields is using, makes it hard to adopt a whitelist-approach where you disable more or less everything and then enable just the functionality you want. Blacklisting (where you specify everything you want to disable) is fairly simple though, but not as secure of course.
For Supershields I have used a combination of blacklisting and running the scripts on serverless instances (AWS Lambda), which limits the impact of a breach.