Best practices for preventing common exploits?

I’m asking for an open discussion on exploit prevention. What do you do to prevent exploits? What would you consider to be “best practices” for this? Also, are their techniques people use that don’t actually work but are still common? I don’t know what sort of exploits are common nowadays.

Here’s my own thoughts so far:

  • Only expose RemoteFunctions/Events that the client could realistically invoke outside of your code and not cause problems (both by exposing only what needs to be exposed and by writing code to do basic checks)
  • Type-check arguments that the client sends to RemoteFunctions/Events
  • Don’t allow server-to-client invocation of RemoteFunctions, since the client could hang the server

What else? What do you do for your games? This doesn’t have to revolve around RemoteFunctions/Events. This could also be client-only environments.

14 Likes

Basically don’t trust anything the client tells the server, and yeah like you said, don’t let the client hang the server (at least on things that stack/will stop code important to other players). That’s the passive part of exploit prevention.

The active part of prevention is a bit more variable. If the player has control of any important things (such as their walk speed, their position, other objects’ positions), you’ll need to be checking that on the server to make sure the client isn’t doing anything dodgy.

That’s all there is to it, AFAIK. FilteringEnabled seems to be pretty good.

5 Likes

I made a time based encryption method for my remote events and functions that has worked flawlessly for a while now.

You can also do checks on server and if they have little latency and fire something too much then it might be suspicious. You can also do positional or regional (noclip prevention) checks, again based on latency.

I scramble the names of all my events and then add a lot of fake ones that are also scrambled so if you start firing at random you’ll hit a fake one and then I peg you as an exploiter on your datastore.

I also detect requests you send that arent possible, like wearing a skin you dont own or donating money you dont have to a team you cant possibly donate to. All these are taken note of on their datastore.

9 Likes

I do a lot of trickery when it comes to preventing exploits:

  1. Script Obfuscation, renames every variable and function name to a random amount of underscores, very satisfying to look at.
  2. Randomised networking keys and instances, all different each server.
  3. Function environment and ModuleScript trickery to prevent most methods of tampering with the client’s script environment.
  4. Encrypting certain parts of code in LocalScripts with my own custom Lua VM which is randomised each time I update.

This is only a few things that I do to combat exploiters, I have many other tricks that I use.
Most of the stuff I mentioned above (1,2 and 4) are all automated.

5 Likes

I recently just added badges to my game, and I instituted server side sanity checks for them.

Due to most of the map being locally replicated, and the map moving, I need to have client sided bricks for certain areas of the map that give out badges. So with an ontouch event, I send to server, which does a sanity check, like if it’s the right part of the round for a player to have been able to get that badge. Sometimes I also do a distance sanity check. Server-side sanity checks definitely prevent common exploits.

Whenever I fire a remote event/function, I tend to include a key of random characters as one of the arguments and then in the second script, I check to see if the argument passed is the correct key, potentially thwarting someone trying to fire an event through a command line to, for example, kill someone with a ‘take damage’ event.

2 Likes

Lol I see these threads every other day.

I think as @EmeraldSlash says, starting out with filtering enabled is a pretty good move. Having your code manually record movement, and checking if there is some sort of transition between two points, could help you determine wether a player is exploiting.

Thought bubbles:

  • Max player “on-foot” speed.

  • Not allowing the player to even appear in a position outside of the “range” of the position they were x seconds ago.

  • Utilizing the navigation mesh to find if a player can get to an area, or if it is solid, so as not to allow the player to be in it.

  • Having Manual “no-go zones” that push you right out if you are within a region.

  • Dropping a block every few milliseconds at the players position, then getting the magnitude between the “markers” and measuring if they exceeded their max moving distance.

Keep in mind that you have to make sure your methods aren’t hackable themselves. (FE will help a lot here)

Keep experimenting!

2 Likes

A problem here would be Lag if you needed to teleport a user. My fix is to check a player’s ping and factor it in with my antiexploit. It works very well I have yet to be falsely kicked from my anti exploit

3 Likes

As a blanket statement, let’s assume everyone here is using FilteringEnabled. You’re literally not going to be making a successful game without it, thus no need to mention it for now.


So it sounds like the gist of it is the same as it has always been: don’t trust the client at all. It sounds like the “trust” part of the equation is going to vary from game-to-game. For instance, in an FPS, you might need to perform some sanity checks on how often a player is shooting a gun.

Also, just in case you missed it, all games are now FilteringEnabled (it was forced by Roblox a few months ago!)

3 Likes

Untrusted data should go through a few steps:

  1. Rate limiting
  2. Schema validation
    • e.g. type assertions
  3. Sanity checks
    • e.g. discarding OOB or nonfinite values
  4. Optional: Turing tests
    • e.g. calling out aimbots

A cool problem that @0xBAADF00D and I ran into yesterday is NaN poisoning. If a malicious user can introduce a NaN into your game’s economy, they might be able to get infinite items for free depending on how your code is structured:

-- Unsafe: NaN balance will award item
if player.balance < price then
    print("not enough money!")
else
    awardItem()
end
-- Safe: NaN balance won't award item
if player.balance >= price then
    awardItem()
else
    print("not enough money!")
end
23 Likes

Wouldn’t the easy solution be to just listen for when the user wants to buy something, and what they want, but never let them try telling you what their balance is? Keep all that stuff serverside and send the client an updated value any time it changes serverside so they can still display it.

3 Likes

I’m curious to know what these checks on the client by @einsteinK even do xd
(I assume that you can access these things in a level 7 but why can the clients not require your modules in a lower level environment?)

local function checks()
	-- einsteink hack checks https://devforum.roblox.com/t/anti-exploit-draft-mostly-re-rf-protection/32253
	assert(not pcall(function() return workspace.DataCost end))
	assert(not pcall(function() return workspace.RobloxLocked end))
	assert(not pcall(function() return game:GetService("CoreGui").Name end))
	assert(not pcall(function() return game:GetService("CoreGui").SelectionImageObject end))
	assert(not pcall(function() return game:GetService("Chat"):GetShouldUseLuaChat() end))
end

I don’t know how this sounds…but:

Don’t exploiters mainly change variables for their benefit? Or insert scripts? Well, you could basically have a script manage when/what is allowed to change it. Only x script can change xyz variables. Detect new “children” scripts, and delete them if they weren’t original (or added by the game.)

2 Likes

I tell the server I want to buy NaN things. The server agrees and deducts NaN from my balance. I have NaN money now.

1 Like

Oh! I see now.

that check wouldn’t matter really (only if done locally) considering the actual data would be used, not anything from client

I have some questions that I am hoping someone can answer. This would be helpful to know if these are possible exploits or not. Is it possible for a hacker to send events to/from other players?

  1. Is it possible for a hacker to send a bogus remote event from the server to another player?
    For example, they would mimic a server to client event that affects another player.

  2. Is it possible for a hacker to send a bogus remote event from another player to the server?
    For example, they would mimic a client to server event that affects another player.