Is This A Reasonable Way To Handle Exploits on the Client?

check old post, i responded a script against that

no this is not a good way, an exploiter can easily get around it.

What happens when you “copy” a local script from the server to the client. The server sends the client the information about a local script, and the client can choose to do whatever they want. If they don’t want to run it they don’t have to.

It’s futile to do client security, just secure your game from the server

3 Likes

I understand that client security is futile to a certain degree, but would this stop the majority of exploiters who don’t know how to manipulate the game as well? When the client makes changes to the humanoid, the server doesn’t seem to pick it up (from my tests), which is why I did this.

That is a fair point. I don’t know how easy it is to exploit, or what exploiters are truly capable of (I understand they have access to and can modify anything on the client), but beyond that, I am lost.

Would it work to randomize where this script appears in playerGui (I.e hidden inside one of the screen guis, or a textlabel, etc). Would this be enough to stump/irritate enough exploiters until they give up trying to erase it? Thanks for all of your help, I’m doing my best to understand everything. This is my first time trying to design my own anti-exploit.

you only need one exploiter to release the method for everyone to be able to do it – also you don’t need to listen to humanoid changes to combat a lot of stuff.

you can combat walk speed changes by checking player velocity, flying by raycasting, …

1 Like

no it wouldn’t “stump” exploiters.

99% of exploiters are just 15 y/o skids using synapse who don’t even know how to script.

1% of exploiters actually make the scripts and release them to the skids. the 1% are not noobs and can bypass any minor nuisance you send their way.

I recommend reading this thread

3 Likes

Thanks for the tip! I’ve always been confused on

while true do

vs

while wait() do

so the tip helps.

Let me tell you the basic security.
You never trust the client. Trusting that their anti-exploit is not defeated is not the best way of doing things.
No matter how much you try, you are never in control of the client. You can’t make it behave how you want it to be.

Simply put, you must handle anti-exploit server side.
A good amount of it is basically checking if they’re capable of being there. Implementation of that? Not sure. I can think of a couple but I guess I’ll try to implement it first before I’ll tell you.

1 Like

This can work, but it will likely fail.

The exploiter can delete the client anti-exploit then do whatever they want for the one second of no protection.

1 Like

I’d like to point out that no matter how much client security/hacky tricks you do, there’s always the possibility for an exploiter to get past it. If someone is dedicated enough, odds are they will write a whole script just to fight your clientside anti exploit.

For example, pretending I’m an exploiter, once I figure out that PlayerHandler is the antiexploit using a decompiler I can just disable or delete the script everytime it is cloned into my PlayerGui. I’m not entirely sure the contents of the AntiExploit local script itself, but let’s pretend you’re sending my client walkspeed to the server. I could just delete the RemoteEvent or I could create a script that modifies the RemoteEvents arguments (changing the walkspeed argument to what it was originally before I exploited and changed it) before the server recieves them. I could stop other local scripts from reading my data on the client.

Now odds are, you’ll never run into this type of exploiter. Exploiters that know how to do what I just illustrated are rare, but they definitely do exist. All it takes is for them to write it then mass release it on exploiter forums.

The safest thing you can do is just have server sanity checks. Check how fast the player is moving. Check if the player is going through walls with raycasting then punish them accordingly by pushing them back.

Note:
People were talking about performance issues and odds are you’re going to run into them. In 20 player servers every second you’re cloning 20 scripts, naming 20 scripts, destroying the previous 20 scripts and parenting the 20 scripts. I suggest changing wait(1) to wait(5) because then atleast you’re giving the engine some time to breathe.

1 Like

Thanks for the detailed response!

This is definately true, I’m doing my best to handle all of the logic securely so it works properly. My game is very physics/gun system based, which is why I worry about humanoid walkspeed (when altering it from the server, it doesn’t seem to replicate). However, as you said, I will do sanity checks from the server to check the distance traveled (and rubber-band them back).

1 Like

@TESLAC0IL That isn’t a very valuable answer, and no what you said is wrong. It isn’t not very “performant”. I suggest you read about the Task Scheduler.


The above syntax is considered better. In a case where wait doesn’t return anything, the below syntax would evaluate to false and wouldn’t run. This is of course, high unlikely but it’s better to be on the safest side. Rather on the safest safest side.


Replying to @Infinite_Visions, client sided anti exploits will never work. A true anti exploit will be always server sided. If you can’t make your own, here is mine which is open sourced and very reliable and performant:

@TESLAC0IL That isn’t a very valuable answer, and no what you said is wrong. It isn’t not very “performant”. I suggest you read about the Task Scheduler to get a gist of how they work. However, here is a much better answer.


The above syntax is considered better. In a case where wait doesn’t return anything, the below syntax would evaluate to false and wouldn’t run. This is of course, high unlikely but it’s better to be on the safest side. I would rather say, on the safest safest side which is honestly unnecessary.


Replying to @Infinite_Visions, client sided anti exploits will never work. A true anti exploit will be always server sided. If you can’t make your own, here is mine which is open sourced and very reliable and performant:

Check it out here: Bobo Fighter

1 Like

Thanks for the tip! I understand client sided anti-exploits do not work against advanced exploiters, I guess my goal was to stump the “noob” exploiters (who don’t actually know anything about how the game runs). However, I will switch to fully server sided.

wouldnt they just be able to constantly delete the script
I think a better way to do it would be to secretly embed it into a main script in a gui

Your “anti-cheat” can be bypassed in a couple of lines.
Last time I checked, :Destroy() disconnected all events.

local plr = game.Players.LocalPlayer
plr:WaitForChild("PlayerGui").ChildAdded:Connect(function(obj)
       if obj:IsA("LocalScript") then obj:Destroy() end
end)

Also, if this doesn’t actually stop your script first, exploiters can just use the getconnections function to disable all connections on an event (which includes your .Stepped and all of your .ChildAdded and .ChildRemoved)

If they wanted to go a different (smarter) route, the can just:

local plr = game.Players.LocalPlayer
plr.CharacterAdded:Connect(function(char)
       char:WaitForChild("Humanoid").Name = "YourAnticheatWillHangForeverNow"
end)

A fourth way they can bypass this altogether is to just hook __newindex and prevent your localscripts from actually setting any humanoid property that can affect them (walkspeed, jumppower, health).

Do not waste your time on client anticheats. They can be bypassed in 1/10th of the time it took to make them. Secure your server instead.

1 Like

It might stop skids that can’t find a script for your game, however overtime exploit developers would discover your game and that exploit they made could prevent your script from re adding it. My best bet is just try adding a RemoteFunction that checks your script every minute and if something is wrong, you take action, and add sanity checks to your RemoteFunction. But please, don’t take my word for it, I’m not an expert at exploits.

1 Like

Thanks for your feedback! I did end up scrapping the script, it was mostly a test. I ended up doing it all server sided, which has worked out well so far.

Lets say you do end up doing your local script client-sided (not recommended). If you parented it to nil, would exploiters ever be able to delete it? I’m just curious.

Exploits can see whats inside the mysterious place of nil. Basically they can still delete it if their injector api has getnilinstances or something similar. So setting a local script’s parent to nil won’t help

1 Like

Exploits are often packed together so that an attacked system is checked against a wide range of vulnerabilities; once one or more are detected, the appropriate exploits enter. Exploit kits also widely use code obfuscation to avoid detection and encrypt URL paths to prevent researchers from unrooting them. Malicious developers even create exploit kits, which are collections of exploits often bundled with other software

1 Like

Could be bypassed with the following code

local LocalPlayer = game:GetService("Players").LocalPlayer
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local HumanoidRootPart = Character.PrimaryPart

local RunService = game:GetService("RunService")

local function Disable()
    for i,v in pairs(getconnections(RunService.Stepped)) do
        if v.Function and typeof(v.Function) == "function" then
            if string.lower(getfenv(v.Function).Name) == "antiexploit" then
                v:Disable()
            end
        end
    end

    for i,v in pairs(getconnections(Character.ChildRemvoed)) do
        if v.Function and typeof(v.Function) == "function" then
            if string.lower(getfenv(v.Function).Name) == "antiexploit" then
                v:Disable()
            end
        end
    end

    for i,v in pairs(getconnections(HumanoidRootPart.ChildAdded)) do
        if v.Function and typeof(v.Function) == "function" then
            if string.lower(getfenv(v.Function).Name) == "antiexploit" then
                v:Disable()
            end
        end
    end
end

Disable()

LocalPlayer.PlayerGui.ChildAdded:Connect(function(v)
    if v:IsA("LocalScript") then
        Disable()
    end
end)