Safety of in-game loaded back-end script and module scripts

Hello!

I’ve been developing a game that includes a user-generated map feature. Players can create maps, write event scripts, and load these maps into the game using InsertService. Recently, Roblox introduced a new Ban API, which simplifies the process of banning users. This is a great feature, but map creators (users who design maps for my game) could potentially exploit this function.

Thus, I’ve been working on implementing restrictions for scripts to prevent abuse, but I’ve encountered an issue.

Problem:

When we enable scripts in-game, there’s no reliable way to debug them or execute just the first line of code for testing purposes. I attempted to fix this issue using a particular principle:

This image is from the TRIA.os server.

This solution works for a single script and restricts the use of certain modules. However, I wanted to design a more advanced Moduled Event Script System. As we know, in C++ we can use classes, so I tried replicating this behavior in Luau using metatables.

Everything worked fine, but when we require(module), a non-initialized module gets initialized and starts executing its code immediately. For example:

Server Script:

-- Type Map is a custom type
local CurrentMap: Map = randomMap()
local mapHandler = require(CurrentMap.MapHandler) -- We're requiring MapHandler or ModuleEventScript

CurrentMap.MapHandler:

local Players: Players
-- Some code

Players = game:GetService("Players")
-- Some code

Players:BanAsync(--[[ban someone]])

-- This code will execute with server-side permissions to ban players

local module = {}

-- Functions

return module

The issue arises because this code executes as soon as the module is required. I’m aware of the setfenv function, but I need a way to intercept the module’s environment before it executes.

Question:

How can I set a module’s environment before requiring it, to prevent its code from executing immediately?

Thanks!

I’m pretty sure you can’t set a module’s environment outside of the module itself. You need some kind of way to check the source code, right? You could have a http URL saved inside of a string value under the map which links to the map source, from there you can request it and check it as a string before using loadstring() to load it. But, that system is not great.

I think the issue mainly lies with letting users use scripts, and I think this is why Crazyblox changed it in Flood Escape 2 (noticed you are interested in some flood escape type games from looking at your profile so I used FE2 as an example as it has a system like this).

Basically, any system that lets users write scripts is a vulnerability because Roblox doesn’t let us read script sources at runtime. I think your safest bet is doing what Crazyblox did and converting to a scriptless system, using timelines-like structure, instances to control when and how things happen.

A long stretch is making your own sort of language for the maps, having users comment it in a script, limit it’s capability and then create your own parser and translater to Luau so it can be executed.

Have thought about that, but the problem is not in implementing that. FE2 has their Timelines system, but you can’t make some complex code with it and that’s the problem.

How complex are you trying to go with your system? You’re going to need to try and find a balance between freedom of maps and game security.

I know I need to find a balance between freedom and security, but you mentioned that I can use HTTP to get the code as a string, which is actually a great idea.

This way, users can update their scripts without needing to update the model.

You could have them upload it to GitHub, I’ve seen exploits hide their code and get it with a http request under a https://raw.githubusercontent.com link, that’s a good way to retrieve it for your map’s code.

Just be aware of rate limiting!

(im not sure if it costs anything or something like that so make sure to check that stuff first)

1 Like

Thanks, already done a simple example, and it works fine! I really appreaciate your help!


1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.