A complete guide ~ How exploits work & how to best prevent them

here, let me let you all in on a idea that most developers overlook and I, due to my job in a studio have not been able to code up myself.

The reason exploiters are able to exploit the player’s character is because the character is all on the client. If you ever noticed when you yourself lag, your character is walking just fine, on your client but n for others, you’re lagging and for you, they are lagging.

This right here is the very reason exploiters can exploit their character and for instance, teleport across the map.

Now, what you’d ideally want to do if anti exploiting is so important to you and top priority. You’d recode the BACKEND of the player controller and have the server side know the position on the server and all the client ever really does is predict where the input in the server is and if that input is offset from the server, then the client automatically corrects itselfand if a player tried to alter this in any way, shape or form on the client, thanks to your server side, you can detect if that player might’ve altered this at all. This is a true fix to exploiting. Not exploit prevention, but it makes the player’s character unable to really move on the client, rather, predict where the client moved to begin with and if the server and client posiion is offset,then the client will “lag back in time” to where the server’s last known position was.

Of course, this has one major drawback, which is the deal breaker for a lot of people. Say someone had 400 ping, the game would be literally unplayable cause you’lll be lagging back in tine constantly cause the client will constantly be offset from the server to where it’ll always try and correct itself to the server’s last knownposition and repeat. That’s a majo drawback so if you are looking to run a game where lag has a huge difference, you’ll need to choose which is more important. 100% play ability or a more secure player controller.

8 Likes

Not too sure how your post is much different to the Exploiting Explained post but nonetheless, I have a few things to say:

This is an interesting discussion point already, as we truly need to define what is “as much as they can”. Roblox certainly have implemented quite a fair share of security checks, such as the memcheck, random hackflags within the regular client and even Luau has some security checks for stack checks and the like.

However, even with all that, you can execute code fairly simply without needing to bypass the majority of Roblox’s security checks.

Moving away from client-side security though, Roblox are fairly naive when it even comes to their client → server architecture. Roblox will accept a lot of information without any scrutiny or sanity checks for it so in that perspective, Roblox has a lot of room for improvement - and the Roblox client is no exception.

Ultimately, it’s always going to be a cat and mouse game and a lot of Roblox’s security issues can be attributed to technical debt.

This “shuffle” you’re referring to doesn’t have a massive impact to exploits. It’s part of the Roblox client build process and a lot of functions and whatnot that exploits need to function can be found by scanning for byte signatures within the client.

Roblox update on a weekly basis as part of the Agile development system. This is why they use fast flags and have regular meetings, it’s simply just part of the development life cycle which a lot of companies adopt in one way or another.

With regards to server-side exploits on Roblox, it’s unfair to say this is due to developer stupidity because even in the real world, exploits happen due to insecure dependencies, etc. This is why auditing your code is important, making sure to use open-source libraries and understanding what you’re working with.

Roblox is an ideal place to share these types of malicious backdoors, as a lot of the developers on the platform are not familiar with real world development standards and processes - such as code review, etc. This doesn’t make a developer on Roblox “stupid” but simply inexperienced as they’ve not had the real world experience to develop their skills. Perhaps making a code review guide for Roblox would be more beneficial than this post?

This entire section you’ve written doesn’t really cover a lot about making their scripts fail. You’ve even mentioned that this can be fixed by using GetService() which is good practice, you’re right. At the very most, it’s a very slight inconvenience to an exploiter.

If you’re looking to protect your game more seriously, you’ll focus purely on server-side security and always verifying the data that’s given from the client - even if that’s as simple as character position, since with Roblox being naive as I mentioned, it’s possible to spoof your position via Roblox’s replication packets - the RakNet bitstream is a lot of fun to play with :wink:

I’m going to let @GameAnnounce say the rest, as he’s also really experienced with all this as well :slightly_smiling_face:

16 Likes

First and foremost, not to rain on your parade, but this is not really a “complete” guide. There are many nuances to exploiting and for that matter exploit detection and deterrence.

This section is redundant, there aren’t really different ways to be able to execute scripts on Roblox - there’s no compiler on the client. It’s as simple as generate some bytecode, feed it to the deserializer, and run.

This section is almost entirely opinion and speculation, but incorrect speculation at that. The battle of developer v exploiter is one entirely of catch-up. Preventative measures will always be circumvented: where there’s a will there’s a way.

I don’t agree that Roblox doesn’t do more because they can’t due to “risk of breakage”, but instead that it’s inherently difficult to do anything to prevent or detect exploits that won’t be found out by anyone who has Roblox installed on their machine. By design, you should never trust the client (a mistake Roblox made years ago and band-aided with Filtering Enabled). You should always assume someone is going to reverse and understand your code since they have it on their machine.

The downside of adding more “security” is the degradation of performance - especially in the Luau VM if any countermeasures were placed in there. The tradeoff is not worth it if it will be circumvented within the week or two.

I’m not going to elaborate on this too much, but there’s a lot more that can be done (cough, cough Roblox please hire me).

This isn’t exactly true, Roblox added shuffling and member obfuscation a few years ago. The weekly updates to the best of my knowledge aren’t to inconvenience exploiters, but just how Roblox works because it’s expanding so quickly and there are always new features to add. New technology, new standards!

Checking for window names is redundant, and I’m not sure why it was ever done in the first place. Cheap security to stop those who are new to the field.

I don’t like these terms, they’ve been bastardised over the years. You cannot do anything against a user who can execute arbitrary code on the server, only Roblox can make a difference here by patching the method used (friendly reminder: LogService:ExecuteScript was a thing lol). However, filtering and scrutinising code you’re putting in your game is good practise. It prevents malicious code seeping into your game and potentially allowing bad actors on the client manipulating your game.

They don’t at all. Maybe I misunderstand the wording you’re using but, they can’t do anything about it and nor can you. It’s a case of writing inherently safe code where the server is authoritative.

As for the rest, I’m not going to repeat what others have said but I will say: be careful of what you’re checking and how you’re checking it. Errors, Names, and Properties are all well and find to verify when you know what the bounds are. But if you don’t…well…that’s different kettle of fish

22 Likes

Correct me if I’m wrong, but can’t you do :FireServer(“legitEvent”) and then do in the handler, :Connect(function(Event)
if Event == “legitEvent” then
—Do stuff
Else return end?

Sorry I’m on mobile so I can’t do the lua symbols.

2 Likes

The exploiter could easily use something like RemoteSpy and figure out that they just have to fire the event with “legitEvent”.

You shouldn’t try to use any of those weird key techniques, just don’t trust the client since the end user can do pretty much anything.

4 Likes

Correct me if I’m wrong,

What can Exploiters do

Exploiters can disable functions in a Client side script,

For example Player:Kick()

You can’t kick them from Client-Side, even if you fire a remote to the server to kick the exploiter, it won’t work

They could do simple stuff like Walkspeed and JumpPower, they could also Fly

Also they could Decompile Client scripts and checks how your system works on client and how to abuse remotes

Try not to include important stuff in a Client side script

Don’t make Client sided Anti Cheats because its pretty much useless and exploiters can delete them or bypass it

Remember Exploiters can control anything related to Client Side so be careful.

NetworkOwnership

Recently exploiters can do custom animations because of SimulationRadius

They can do other stuff as well, they could bring players with Tools and Network.

  • They can control Not Anchored Parts

  • They can control Hats with network

  • They can make objects with hat parts ( Delete meshes from the hats )

MaximumSimulationRadius has been patched by Roblox.

SimulationRadius Patch:
NetworkOwnership Exploit Patch

Backdoors

They mostly come from free Models

Exploiters can launch a backdoor check, if you have a backdoor in-game, the exploiter has Server side access, So please be careful with free models.

You could easily prevent most Backdoor checks by inserting a remote and if the Exploiter fires it, it kicks him or logs the Exploiter or whatever you want to do with the Exploiter, this won’t be a lot useful.

Securing your remotes

Don’t do checks on Client-side,

for Example a Buy button, instead of checking from Client-side just fire the remote and let the server check the currency that the Player has since Exploiters can manipulate Client-side.

if your remotes aren’t secure, Exploiters will 100% abuse it

12 Likes

There is a lot of truth some of what you said. The fundamental client-server model of Roblox gaming is a bit of a mess, with various compromises made to keep the game playable, but which also leaves open doors for cheating.

There indeed is an entire community dedicated to cheating, and the manpower behind cheat development is huge, like so huge that client-side anticheats are only good on a rolling basis.

There is also a lot of scripted models created and botted to the top with unscrupulous intent. These models use heavy obfuscation to hide their true intent and try to seem innocent by containing comments along the lines of “obfuscated to prevent stealing” or “this script is required by Roblox Studio. Do not delete.”

However, I have some criticisms.

Many of the front-page backdoored items go as far as hiding the keyword itself behind more obfuscation so you don’t find it with Ctrl + F, usually through a combination of getfenv and insane string manipulation. Here’s a simple example:

local a = getfenv
a()[string.reverse("eriuqer")](12345)

I don’t like being verbose with GetService throughout my game code.

For publicly-shared scripts, yes, anything can happen to service names, which is why it’s good practice, but for game code written for its respective game, I’m historically more productive using game.ServiceName whenever it’s available. Autocomplete works better with that. Coupled with the fact that many exploits, whether game-specific or in-general, account for randomized service names, it doesn’t seem worth the trade-off, at least to me.

Also, take note that randomizing Workspace is useless since there is a hard-coded property such that game.Workspace will work regardless.


What if the cheater fired the remote with normal amounts a million times, instead of once with an insane amount? Okay, let’s use a rate limiter! Then what if the cheater is firing the remote when they are in a location where they shouldn’t be awarded money at all? Okay let’s use check zones in the game world! Then what if a cheater briefly teleports into a valid zone and then fires it before your anti-teleport example code gets around to detecting them.

The point is, it would be better that only server scripts can award money. There should be no remotes for awarding yourself money whatsoever.

Except maybe in singleplayer games where cheating isn’t a problem for anybody other than the player cheating.


There’s also other things that you didn’t cover, such as undocumented replication behaviors and the ways they could be dealt with. So I would recommend you do some research to improve your coverage of the topic.


I’m like, “oooh; That’s brave to admit.”

9 Likes

It will work. the kick on the server has to work because it cant be tampered with.

1 Like

exploits have bypassed this now, thanks to this now they also have figured out to get your country and osPlatform

What he means is that firing a remote event can be intercepted by the client. So if you attempt to kick via remote it can be disabled from going out too.

5 Likes

I really don’t get the point of this post. The main server-sided checks you should have to prevent exploiting is anti-teleport (checking position), anti-speed (checking velocity), and anti-noclip (raycasts/:GetTouchingParts()). Renaming services is a waste of time. The only thing you should worry about regarding client-sided anti-cheat is a quick LocalScript that detects changes in the Humanoid (to prevent the script kiddies). Remotes are easy to protect. Just make sure that the player is actually allowed to fire it using some if then checks. This isn’t really a “complete guide” if the only server-sided check covered is position checks. You also need to add a lot of checks to your script to make sure it doesn’t error and let exploiters roam freely. You have to check to make sure the character exists before it is referenced, and then make sure the HumanoidRootPart exists using if :FindFirstChild().

4 Likes

They can’t get your country anymore, roblox fixed it, They removed it from HiddenProperty, and OSPlatform as well.

Someone that I’m friends with made a script where the moment you hit inject/attach on synapse it kicks you. How is this possible?

4 Likes

Likely does something unreliable like checking spikes in memory using Stats service. This is extremely unreliable and the roblox client is extremely unpredictable with memory spikes. I’ve seen from the dev console it go from 300 to 400 before.

Exploit programs being injected should be the least of your concerns, your concern should be your remote security as well as anything you can detect server sided that gets done to the character, and small checks on the client if you can

4 Likes

Is there any other way aside from spikes?

Don’t spend so much time and effort to detect an injection. You will most likely have many false-positives, and actual cheaters will be able to bypass any system like that. Just make cheating impossible. Make it impossible for players to teleport, speed hack, or noclip. This will discourage cheaters from cheating in your game, and will also minimize the effectiveness of cheats in your game by a lot. It’s the best we can do as developers to prevent cheaters from ruining our games.

2 Likes

Speed hacks and fly hacks really don’t benefit players in my game, what Im looking to prevent is people stealing my map, I already had a lot of ppl message me on discord talking about how they are going to enjoy leaking and using my map. DMCA claims are easy and I can easily take down copies but my concern is preventing it.

There is no preventing it. Such is the world of game development on any platform. Does the client have to load it? The client can do anything with it.

6 Likes

Do exploits add new scripts some-where?
If so, then can’t you just delete it when its added?

1 Like

No, exploits work by directly executing their code on Roblox’s VM. This is what a normal script does but exploits will skip creating a reachable LocalScript instance

You might’ve been confused because there’s some “anti-exploit” scripts that kick a player if a new LocalScript is added to ReplicatedFirst.
This was because RC7 originally put their script variable’s instance into ReplicatedStorage, but no exploits do this any longer.

However, most exploit do create an actual LocalScript instance, but it’s parented to nil so it’s unreachable by other scripts.
Perhaps if you catch an error you can traceback the callstack and see what script errored, if it’s parented to nil and not an expected script, it’s probably an exploit script.

5 Likes