Disabling require(id) by default

As a Roblox developer, it is currently pretty scary to insert any types of free models into Studio. Even if I’m just looking for an old SpecialMesh, I always run the risk of inserting something that contains a malicious server-sided backdoor. While I personally am aware of these risks and know to screen anything I insert, I also imagine that many Roblox developers aren’t, considering the amount of times backdoors like this are used to cause significant harm to games created by smaller groups.

require(id) has already been under fire from members of the community and Roblox staff for this exact reason. While I previously defended require(id) even for closed-source modules, I didn’t see the amount of damage being done with this feature at the time.

As far as I’m aware, require(id) is a feature that is only rarely used legitimately by developers. While it does have its uses, in cases where it is useful, this should be a setting that is manually enabled by the developer. Allowing third-party code to be loaded into the game at runtime should be a conscious decision made by the developer.

Sending HTTP requests via HttpService is already disabled by default, and Studio provides a setting that has to be manually enabled for scripts to be able to send these requests:

I suggest we have a similar switch, defaulting to “off”, that allows us to choose whether modules can be required by ID in our games. If this runs too big of a risk of breaking existing games, the setting should default to “on” for any existing games and to “off” for any new games.

Alternatively, this setting could specifically limit third-party modules, i.e. modules not created by the user or group that created the game.

If Roblox is able to address this issue, it would improve my development experience because I could be confident that the only scripts being run in my game are the ones I can actually see. I know that a single script with one well-hidden line of code isn’t going to side-load a huge package containing admin commands and weapons granted to players in my game for paying some third party.

23 Likes

As a Roblox Developer, I use plugins that require third-party modules at runtime, but it is impossible for me to disable it. If this feature is implemented, it would improve my developing experience because I will know full-well that the scripts running in my game are only my scripts and not third-party modules.

My current workflow when I want to run a quick test in Studio:

  1. Click “Manage Plugins” in Studio.
  2. Disable all plugins that require a third-party module.
  3. Play-test the game in Studio.
  4. Click “Stop” to exit play-test mode.
  5. Go to “Manage Plugins” again.
  6. Re-enable all plugins that were previously disabled to start using them again.

Plugins are so useful that I shouldn’t need to disable, just to re-enable and use them again after a quick test.

1 Like

My solution was to add this to the beginning of each script (both for the client and server) in your game:

local OLD_REQ=getfenv().require
getfenv().require=function(s)
  if typeof(s)=='number' then
    error('Importing by ID is not allowed!')
  end
  return OLD_REQ(s)
end

I learnt after a rew replies that it sucks because:

That is not a feasible workaround to this request.

————————————

1 Like

getfenv is hellishly hacky and recommended against

This also wont work because every script has its own function environment.

Plus you dont need to getfenv here, just overload the global directly.

3 Likes

Bonus points for also being in the process of getting deprecated.

3 Likes

I completely forgot that global variables aren’t locked, unlike the metatables some hold within themselves!

game = {} -- is perfectly valid.

but…

setmetatable(game, {}) -- you need to use a third-party script executor and a couple of other prior function calls to do that!

Thanks for the pointer by the way!