Best way to prevent cheaters from using remotes?

Yes - any time that data is sent anywhere on the client, the exploiter can intercept it.

So your process would be:

  1. Generate the code on the server - send to client
  2. Client gets code, then does things then sends the code back to the remote
  3. The server checks the code from the client and compares it to the previously generated code
  4. If it matches, then do stuff.

However, the exploiter can actually stop the process and interject:

  1. Generate the code on the server - send to client
  2. Exploiter stops the script that sends the code back through the remote and instead does their own thing to the remote
  3. Exploiter sends the malicious data along with the generated code back to remote
  4. Server checks code, it matches, server proceeds with malicious data.
1 Like

Wait I have a question.

Would setting the remote event’s parent to nil make it impossible for the exploiter to access, since the script already has it defined

local event = game.ReplicatedStorage.Event
event.Parent = nil

event.OnClientEvent

and since it stays on the replicated storage for the server you could just fire,

or would the client not recieve any calls?

I believe that setting the remote’s parent to nil will still let it be functional (so long as you don’t use Destroy()) but only because I know that most of the popular exploiting clients come with a feature that lets you scan nil for remotes.

This is not a good solution either.

It wont help.
Most paid exploits out there (and even some free ones) have a function called getnilinstances() that returns an array of all objects parented to nil.

Ok well exploiters suck!

I thought I was smart.

Maybe if you only use the event once delete it afterwards

KeyCheck.OnClientEvent:Connect(function(key)
  code = key
  KeyCheck:Destroy()
end)

I don’t really want to do sanity checks all the time since it just seems a pain but I guess its the only secure way

Remember that Object:Destroy() works by parenting Object to nil.

That will not help either. Take a look at this flowchart I made:

The exploiter can have full control over remotes. You can delete the event afterward, but it’s too late by then. The exploiter can stop the script midway through its execution. Before the local script fires the remote, the exploiter can tamper with it in any way they please.

You must do sanity checks, it is the only way.

Want to get even more paranoid about security?

Roblox uses a legacy client-server model in which the client still retains full control over local physics and their own character. This means that they can set their own walkspeed and position among other things. The server cannot even detect the changes in walkspeed without having to do some math.

You could try making an authoritative server model in which the client literally only handles User Input and GUIs, but they become very slow and unresponsive most of the time and take a load on the server.

You will never be safe from exploiters, and that’s just something you have to accept.

If only there was a way to send data to a specific local script

remoteEvent:FireClient(player)

Yes I know that but I mean to a specific local script not a player in general

Most anti exploits with be bypassed with ease by exploiters who know what they’re doing. Most the time you’ll have a script kiddie trying to act cool in front of people and then get banned because they get caught by an easy check. You could check memory spike on the client for injections but that’s only if you know your local scripts don’t create big spikes on their own and even if you could if it didn’t catch them on injection they could just delete your current client checker. You could use client sided anti exploit to check if they change walkspeed etc but they could be deleted. Although it would catch a handfull if they are smart enough to bypass that you should probably protect your server because they are probably there for more damage

Actually - that wouldn’t help either. Exploiters can potentially have complete control over any local script you make. No local script is safe because exploiters can change it even if it is mid process.

So even if you obfuscate it, add a bunch of keys to it, and only send the code to the one specific local script, the exploiter can access it and change it to do whatever they please. The exploiter isn’t just adding a new local script, they are able to change an existing one. Oh and anything you send to them gets sent to their computer, so they can read everything you send to them even if Roblox only provided the data to one script.

Important Note: This will most likely not be the case. Very few exploiters are dedicated or smart enough to know how to do a complete client takeover. You should still watch out for them though just to be safe. It’s always best to prioritize the worst case scenario when dealing with security because typically you will stop most lower forms of attack.

2 Likes

It’s safe to assume that an exploiter can pass any value through a RemoteEvent. Do not have the client send/handle important information. Instead, script your game so that the client only passes information to the server such as the player clicking something, pressing a button, or any other form of interaction/command that must be performed on the client. Handle the actual logic of processing such an action on the server. If the action is something that is only supposed to be performed under certain circumstances, validate those circumstances on the server.

To give an example of what I mean, consider a shop. You do not want the player to click on a button and then have a RemoteEvent send the price of that item to the server (which is then blindly trusted). Instead you want the client to tell the server that the player pressed that button, and have the server check its own price value for the item that the player is trying to purchase. This way the player cannot send a price that is lower than what you want them to pay. If the player is supposed to be in a certain area to access the shop, have the server check that they are in that area.

If you secure all of your RemoteEvents in this manner, you should not have to worry about exploiters misusing them.

@SSSpencer413 @Neutral_User
I just wanna say thanks for telling me all of this, Although only smart exploiters will be able to bypass methods I use you’ve told me how. Now I finally understand what happened to my game

1 Like

You can use a code encryption system based on a random value in the workspace (viewable by client and server).

I have created this for my games and it works perfectly. You generate (10 digit alphanumeric codes) as many codes as you like in the server (I recommend around 100 to 1000) and then send the to the client on joined. The client and server will have the same table list of codes and every time they send that remote to the server they also send the code according to the value in workspace.

Example: When sending a remote (pressing a button for example) the workspace value is 47, the client will look for the 47th code in table and send the key that’s assigned with that number to the server, the server will check the workspace value and get the key for that number (47) then it will check the key that you have sent. If they are the same then you sent the remote! No script is going to be able to randomly generate a 10 digit alphanumeric code. (By the way the workspace value changes from 1-1000 randomly)

There is a problem with this like on join. If there is a way to remote spy a execute to the client on join then this system is busted. Also I don’t know if players are able to view configured tables inside of a local script. However latency doesn’t effect this which is pretty cool. I know this isn’t the best way but its better than nothing.

My best guess would be sanity checks, server validation, and the occasional honeypot

Sanity Checks
Basically check if what the client is doing makes sense. If the values they are sending are within reason, and if the values are not coming in too fast/too slow. For example, if the same remote is fired with a stupidly high value, its safe to kick that user

Server Validation
Similar to sanity checks, make sure all of the data looks right, like if its a shop script. Make sure that user has the right amount of cash, if its a ban script, make sure that user is an admin, ON THE SERVER

Honey Pots
Not too effective, but can help weed out exploiters. Make one or two events that are named like ‘GiveAdmin’ and ‘GiveCash’ or something, and then hook those up to a ban script. They are not the most effective, but they can get rid of the dumber exploiters

Here is a nice thread going over everything

Just above all, Never fully trust the client and what it says
Whenever possible, check it on the server

1 Like

if its clientsided its easy to abuse, you should try to make the remote work for the server

Could you explain more about your approach?
Cause, if a value with a number is in the workspace, me as a exploiter could check the value to get it when it changes, collect the number, then fire the remote sending the number found in workspace, your server side checks the number and it matches with the one I collected, when server side change the number I check it again and fire the remote again with the new number. (well not sending the number, just use it to get the “key” from the table server gave me on join)

Another idea: name your remotes random things, like random letters and numbers that make zero sense, and add in one or two honeypots that are named equally random things. if the exploiter can’t tell what an event does, they may just fire it and see what it does.

Also for sanity checks, you can make sure the right amount of arguments are supplied to remotes, this will help with preventing an exploiter from randomly firing events

You’re not sending the number, you’re sending the key that’s assigned with that number that’s in the table of the local script that’s sent to you on join.

I have no idea if exploiters can check the configured table in the local script since its empty in the beginning but its better than nothing.