Scripting Helpers is winding down operations and is now read-only. More info→
← Blog Home

Hacker prevention: Filtering and LoadStringEnabled

One of the most frustrating situations of a Roblox game developer is when your place gets hacked. You put some serious time into creating your game and then someone stops at your place and totally wrecks it. In most cases, this is only limited to the current server online, but sometimes these hackers go even further: they wipe your players data or steal your place, putting it up as their own.

We couldn’t really do anything about it, until Roblox decided to create some security mechanisms. They saw they couldn’t fix the exploits as fast as new ones were found. Therefore they created a waterproof system which prevents any person who actually gets access to execute scripts to replicate (upload) their changes to the servers and thus spreading it to all other players in the game.

Exploring the CFrame API

Roblox engineers have now given us a reliable option to prevent these exploits, called Filtering. This filter will, well, filter any change a client makes to the server. It uses a white list: only certain changes are allowed to make, all others are not and will silently be discarded. This does lead to a huge pain when trying to shift from a non-filtered game to a filtered game. You will need to rewrite all parts of your code which involves changing things to the server which must be replicated to everyone. These are mainly changes to the world: insertion of bullets, recoloring parts, creating buildings…

Imgur

So how do you do this? First you must enable filtering: Set the option Workspace.FilteringEnabled to true. There are just a few parts that are actually on the white list. Two of them are RemoteFunctions and RemoteEvents. Their behaviour is similiar: you basically connect on the server or the client to this remote instance, and then you fire it. You can use the events in a similiar way as normal events. You can therefore connect multiple functions to run once you fire the event. If you connect to events on the client, you would normally use the server to invoke these events. You can do the same for client-server connections.

This is a sample server-client connection which explains the use:

-- Server
-- Creation must also run on the server. You can also manually create it before you upload the place.
local re = Instance.new("RemoteEvent", game.Workspace)
re.Name = "Test"
re.OnServerEvent:connect(function(player, arg)
    print(player.Name .. " called with: "..tostring(arg))
end)
wait(5)
re:FireAllClients("Test", 1, {}) -- To fire only one client, use :FireClient(player) with player as player instance.
repeat wait() until game.Workspace:FindFirstChild("Test")

local event = game.Workspace.Test

event.OnClientEvent:connect(function(arg1, arg2, arg3)
    print(arg1, arg2, arg3)
end)
event:InvokeServer("Hello from a player!")

If you only want to connect to a single function you might consider using RemoteFunctions. This can only hold one function to execute (for both client and server) which makes it ideal for procedures, such as cleaning up the workspace, recoloring a brick, etc.

You do this by defining the functions OnClientInvoke and OnServerInvoke. For example:

-- server
local rf = Instance.new("RemoteFunction", game.Workspace)
rf.Name = "Test2"
function rf.OnServerInvoke(player, arg1)
    print("Function invoke from ".. player.Name .. " with: ".. tostring(arg1))
end)
-- Client
repeat wait() until game.Workspace:FindFirstChild("Test2")
game.Workspace.Test2:InvokeServer("Hello RemoteFunction!")

RemoteFunctions can also return values. Events cannot do this!

Imgur

I've only been positive about Filtering so far. There is one issue though: if a hacker figures out how your remote instances work, they can still hack the place. If you got a function for example which is game.Workspace.RecolorBrick, then a hacker can try to recolor all bricks by trying some arguments: the brick as first argument, the BrickColor as second argument?

The last prevention you should take is to disable loadstring. Loadstring is a function where you input a lua script as string. It will return a function which you can execute. Try loadstring("print(1)")() for example. If you disable this then exploiters will get a hard time executing code. You will find LoadStringEnabled in ServerScriptService: it is disabled by default. If you enable LoadString, you cannot use PointsService! Also, this can be changed at any point where you are forced to remove loadstring. In other words: don't use it, unless you have a really good reason and you enable hackers to execute their code in your place. If you don't allow Filtering, then you should also not complain about hackers to Roblox: they have given the tools to prevent this!

Posted in Scripting Tips

Commentary

Leave a Comment

SpicyBuilderclub says: June 29, 2014
Wow, great job.
rollercoaster57 says: July 24, 2014
I enabled it on one of my games, but then nothing would work, i did that in the morning, but then in the afternoon, when i was testing my game in school, i finally figured out why you couldn't shoot the gun, or press the elevator button. They should make it so the creator can adjust the allowed list for things.
buoyantair says: April 21, 2016
;-;
EpicMetatableMoment says: June 13, 2018
Just going to say it. Even if loadstring is disabled there are popular exploits out there that can still run it.
ErtyPL says: March 2, 2022
As EpicMetatableMoment said. That's not helpful in terms of fighting with exploiters. If you want secure your game strategic gameplay/economic mechanics just contact me since I'm experienced in exploiting and know how to protect key elements of the game.
ErtyPL says: March 2, 2022
"Roblox: they have given the tools to prevent this!" That's not true.