How you should secure your game - A beginner guide for secure networking and developing anticheats

Thing is remote spies only log :FireServer and :InvokeServer calls made by their client, plus if you are firing these at an arbitrary rate with fake names surely they will notice that and just know not to fire that remote with a real username.

I meant that the client itself would have a random script fire a random argument name. Possibly whenever a player leaves it could fire their name blankly?

And with a simple check (logging which player left, giving a few seconds grace period so non-exploiters aren’t banned) the server could detect who’s exploiting and who isn’t.

For advanced exploiters this is easily detectable, but for someone who downloads a free exploit and just wants to make a ban script they can get easily caught especially if they don’t know what they’re doing and if they don’t know “too good to be true.”

Also adding onto this further, what if I created an account on sites where people post scripts for certain games and I post a “ban script” for my game, but in the end it just logs whoever fires it? Easily atleast a few exploiters caught, possibly with their main.

1 Like

But they can decompile local scripts and see that you are doing this. And not sure what “fire their name blankly” means.

There are exploiters who know what they are doing even with free exploits, if it is a skid usually the scripts they copy accounts for anti-exploits for them, so /shrug

They can just read the code…if you think on obfuscating they can just deobfuscate it or just dump its constants and see what it does.

1 Like

I see what you’re saying but in general it’s bound to catch a few mindless exploiters. Implementing it can’t do any harm.

Surely, if skids know how to use a remote spy they will know how to inspect the arguments passed over.

If they notice any pattern that will just help them out even more.

Don’t trust the client.

Yep, this is 100% true! I’d say that tricking exploiters by firing remotes is actually a quite good way to at least catch people trying to reverse your game.

Personally I do think that an intelligent exploiter wouldn’t fall for something like you’ve suggested, but, that’s no big deal.

Here’s a little tip because exploiters have no way to stop this: pull a while true do :wink:
The thing is, modern exploits are very powerful and will and can allow for silent modification to everything down to the setting of very specific properties, or even manipulating active event connections. (I mean, hey, this stuff is documented by them! For example, Synapse currently has a very detailed documentation on their website, and it even tells you what not to do if you don’t want your scripts being detected… Yeah, that’s also a weak point for exploiters too haha)

This is the sole reasoning for my philosophy of “think of it like your script can be directly edited” because the behaviour of directly editing your script can be emulated in at least five or six ways usually. Hell, an exploiter can literally emulate your script’s original source under their environment with any modifications they want, so, even if its uncommon, they can literally edit your scripts.

Exploits are extremely powerful from a client perspective as to be expected! And this philosophy greatly simplifies that into something very understandable.

Here is a great way to catch exploiters. Plain and simple, sanity check. Always. If you have code that accepts something from the client that you can validate with 100% certainty, you can also use that validation. Even if it isn’t 100% certainty, there’s no harm in just reducing your reaction, for example, simply kicking! Vagueness is key, and as such, waiting a random amount of time, such as 30-60 seconds is absolutely, and entirely, something you should do when banning or kicking a player.

Someone reversing your game will be testing various things. Hell, you can even intentionally leave minor vulnerabilities in, but still detect them! If someone reversing your game tries something, they may likely respond with something like “Hey, this does something weird that isn’t intended! I’ll put this on my list for later.” A great example of this in use is in some sort of structure placement code. For example, placing invalid structures. Intentionally make structures that are harmless but appear to be specific to development if you want to! When someone uses these, make it seem like nothing is wrong. Then, after a while, ban the exploiter with a vague message, and they’ll be stuck having to redo everything to find what they can use. The more places this is possible, the more times they have to receive the ban to check. Think about how many times they’ll be doing captchas creating and logging into alts. The longer you wait, the better, as long as it isn’t too long because that means they might be able to get useful information. This is a brutal way to stop people reversing your games.

Lastly, as I mentioned before, while true do is the best form of client kick. In fact, rather than straight out kicking the user, give their client a little remote request a second or so before, maybe even hijack a valid loop! The result? The remote request won’t even be detectable a majority of the time This is, another, brutal way to absolutely 100% annoy the people exploiting your games. This also applies to skidding, obviously! Again, this falls into that idea of being as vague as possible, give them as little information as possible.

Also, uh, don’t fix this EVER please, Roblox, I mean it, because it’s hilarious and useful despite being very weird behaviour (PLEASE, this is too good), but, if you :Destroy() the player and delete their character when it gets added (I believe at the moment Roblox won’t even add their character if they’re connecting) or temporarily pause CharacterAutoLoads (and you should most definitely handle characters dying in the meantime or you’ll have a rare case of actually making someone’s character unloadable) you can get some very hilarious results over a kick. They will technically be connected to your game… And they will technically be connected… But… Remotes will stop working only for outgoing content (omg), they won’t show up in the player list, and they’ll still get replications and stuff. THEN you can send a busy loop to freeze their game, THEN you can kick them just for that extra bit of hilarity for the off chance that they get through ALL OF THAT DEBUGGING.

Before I get into this: This crash is actually a surprisingly safe crash it doesn’t do anything afaik and the method to invoke it is ridiculously convoluted so that’s probably why it’s existed for like 10 years (It actually got reported here too I think)
Another, REALLY fun way to mess with exploiters is to create fake (but real) Roblox crashes so they think they’ve goofed up their code (again, this is actually useful, and will never come up in real code, and I think will actually send Roblox memory dumps automatically for that extra goodness of getting people auto banned, please DON’T fix this issue, although, I can maybe see it still getting fixed anyway since it is technically a crash which is super sad). The easiest, and afaik most reliable and really the only way to do this ever, is to make an addition to the above (because like I said, things get weird) and take advantage of a character load mechanic, and before the Player’s character has loaded firstly set a character to a model (this causes funk I don’t understand to trigger the following epicness), then set the character to nil again, then wait for their actual character to load via CharacterAdded, then Destroy their Player, then literally just Destroy the Character to invoke the crash. This causes something with the LoadCharacter mechanism which only happens for the first character load to break and thus crash immediately with no warning. Sure its a crash but the method to cause it is so convoluted I am very much so hoping this never gets fixed (fun fact: this crash has existed since the earliest studio build publicly available iirc, or at least the 2007 build, again, iirc, so, it’s an OLD crash and afaik has never received a patch likely due to how simply convoluted it is to pull off).

Nonetheless, these are all methods I personally like to employ. In one of my little fun anticheat builds (because I like to make them) I randomly use crashing when a verified exploiter joins and is banned and delay the whole process so they think that their exploit messed up their game permanently, it’s quite fun to think about someone having to deal with everything I’ve done and having no clue any of it is actually them being messed with even if they find out one or two things.

13 Likes

I think the crash is insanely cool and please Roblox don’t ever patch it as I’ll be using it from now on. Honestly I’m shocked I found someone just as passionate about tricking exploiters.

I will definitely be adding your ideas of minor vulnerabilities to give the impression that my game is more vulnerable than it is, and just catching exploiters in the meantime if they decide to use it.

As of now, I have a datastore filled with exploiters (and most likely hundreds of their alts) that aren’t there from any possible false positives (because they’ve fired remotes that should never have been fired, etc). Whenever they join the game, I give them errors such as not being able to open the store, kicking them randomly 60-360 seconds and blaming it on a ‘Datastore error’, etc.

I also add random extra parameters to whenever I fire stuff from the client to the server. I know they can easily detect what I’m firing and copy it, but exploiters using free exploits they found online won’t be able to detect it unless they’re that dedicated. Which if they are, chances are they’ll end up falling for other honeypots I have placed in my game.

Besides having these large amounts of honeypots in my game, my serverside anticheat (using raycasts + magnitude) won’t ban users/kick them or give them random kick messages disguised as Roblox or my own errors, it’ll just rubberband them if they’re detected as teleporting, speed hacking, etc.

It’s almost fun to create tons of honeypots/random things to throw off exploiters trying to reverse my game as a normal player that isn’t exploiting will never have to see/deal with it. It’s like adding spikes and landmines around your castle as only the people raiding your castle will have to deal with them.

But anyways, thank you for giving me so many ideas. :smiley:

And another thing I’m not sure if you saw me reply with, looking for scripts used against your games on exploiting sites is a great way to detect your vulnerabilities. Instead of patching the vulnerabilities, rewrite the client code and let exploiters think the vulnerability is still there, just to lag them out/crash them/give them random errors.

3 Likes

One thing I’d like to just mention, crashing is something you should really only use rarely in my opinion. Roblox I’m sure doesn’t like the idea of developers possibly triggering crashes in this way frequently (really probably at all), BUT, (might as well abuse it for the greater good of watching the (at least the exploiter’s) world burn :sunglasses:)

By the way, kicking them for datastore errors is something I hadn’t thought of and it’s actually believable. Neat! :smile:

(And your anticheat from the looks of it sounds exactly like how I implement mine! :smile: I have a policy of never punishing for anything physics related even if its literally something like literally just flying around and noclipping because I can really easily just prevent it from happening at all)

And yeah, that’s always good! Having access to the same exploits others will is the best way to patch said exploits (I know some devs of a game I play who apparently have hilarious checks that check for CollectionService tags called “hack” or something because of this)

5 Likes

(post withdrawn by author, will be automatically deleted in 1 hour unless flagged)

Sorry for bumping, but the link’s dead, which sucks cause I really want to see how you did raycasting

Ah, thank you! You can find the fixed link and more info here:

The post will be updated shortly here.

Where can I learn more about this? I never really thought it was a bad idea until you mentioned it.

Well, having a remote which actually adds money for real would allow an exploiter to give themselves money by firing it. Think about exploits like they create invisible LocalScripts in your game, they can do anything your LocalScript can do, and even more (to the extent that they can basically modify any of your LocalScripts without it being possible to detect)

Personally, If I’m 100% sure that the client is hacking, I’d just play a cutscene of me beating them up, and then if they try to rejoin they’ll just die instantly, forever

2 Likes

Do you detect exploits that are parented to CoreGui?

I don’t know of the ways that this is currently done, but client-sided anti-exploit can be bypassed easily, which is the main point I wanted to make when I made this post. Really you shouldn’t want or need to detect UI in CoreGui.

2 Likes

Unless exploiters can prevent local scripts from being inserted from the server to the client, then I presume some client-sided anti-exploits could work. For example, the server could insert an anti-exploit local script every 60 seconds to check if BodyMovers exist in the player’s character to establish if they are flying using BodyMovers.

Once the local script(s) are inserted into the client, they will not be able to disable it before the code executes.

Unfortunately, this is not the case (also, sorry for such a long reply, I got carried away, but, I do hope maybe you might find it helpful :smile:). All local scripts of course have to go to the client since they run on the client, so any modifications an exploiter makes to the client are also going to effect any new local scripts.

There’s nothing you can do to avoid this since typical exploits have essentially full control over the engine and the way your code will execute before it even executes at all, and, in fact, they don’t actually need to run any new code at all even if you yourself run new code, because, well, they can just change how said code runs in the first place.

All Instances are, to put it simply, a lot like a table, just without any keys/values. They are userdatas (just with some special tagging and stuff in Roblox’s code to keep track of the fact that they are an Instance). They have a metatable (which you can add to tables with the setmetatable function) with various functions on them, like __index and __newindex which control what happens when you do various things. Exploiters have the ability to modify the metatables of Instances without you being able to detect it at all, which is actually one of the oldest major features I can recall existing in exploits, aside from the ability to run lua scripts.

This allows them to for the most part change how particular instances work and it allows them to spoof/fake things, replace functions, and prevent you from setting properties, and plenty more.

Most exploits can also modify the globals your code may use, which applies to all scripts, including ones that are running, and ones which have yet to run at all (like new ones you create on the server). All globals, such as game, workspace, print, pcall, etc, even functions they can completely replace.

Some exploits even have some very powerful features for replacing the insides of existing functions so that even if you try to use fancy trickery to compare two functions, you won’t detect it, since they’ve modified the actual function itself.

Exploits essentially have complete control over how/if every piece of your code executes, to a very remarkable extent. A very skilled exploiter is able to circumvent anything you do, and, often times, exploits make it fairly easy for lower skilled exploiters too.

The real problem with client-side anti-exploit and the reason all of that is possible in the first place is because exploits aren’t actually at all bound by Roblox, or lua, or anything like that, it’s simply more convenient and much less work for them to re-use almost everything Roblox does, but then make their own modifications on top by providing special functions like getrawmetatable (which is not a Roblox function, it is one commonly added by exploits to modify locked metatables). Someone writing an actual exploit tool (not a lua script that would run in an exploit) could really write a function that could do anything to anything, it’s just that they often don’t because it’s easier to take other easier approaches by using Roblox’s code more.

Really when you abstract down enough a LocalScript is just a bunch of data in your computer’s RAM, and the code on it is also just a bunch of data. All of the other things that code may interact with is also just a bunch of data too. And, well, if an exploit wanted, it could modify that data in any way, or even just run Roblox’s own code to do the exploit’s bidding (which is basically exactly what they do all the time)

Even Roblox themselves couldn’t put any code in that could stop exploiting, because exploits could just remove it.

The reality is that client-side anti-cheat may place a sort of “skill gate” but it will never actually stop exploiting. Once someone with the skills inevitably comes along and writes up some code to circumvent that, your client-side anti-cheat no longer stops them at all, and they are free to do anything on the client they want.

That’s why it’s so important to design everything as if any player can do anything in your code, as if they have edit access to your client stuff. You want to assume that any random exploiter could have full access as if they have defeated all of your client anti-exploit, because that tells you what an exploiter can do (and higher-skilled exploiters will inevitably somehow allow lower-skilled ones to do that stuff too, either by sharing their code, or selling it). Once you’re in your server code, however, exploiters can only do what you allow, they no longer have access to the stuff that’s there, and they can only take advantage of what your code does, and what your code doesn’t take into account (e.g. giving a remote stuff you don’t expect)

4 Likes

I really appreciate your reply, helps a lot. Yes, I never write client-sided anti-exploits for obvious reasons but I just wanted to throw that idea out there to see what you thought about it. That being said, I never appreciated that they can control how your code will execute before it actually executes. This is really important to know and just emphasises the importance of writing your anti-exploits on the server.

1 Like

If you don’t mind offering some advice, I have an issue with anti-cheat.

So I have a game where everything is invisible and pitch black. There are also hostiles in the game that are also invisible.

Since its all on the client and so are the parts, because they are replicated from the server, couldn’t the client just make everything non-transparent and be able to see again? I don’t see a way that this could be undone very well.

1 Like