This. Exactly this. Anti-cheats that rely purely on the client never work and never have worked. Poorly made “anti-cheat” resources like this one are even the sole purpose I wrote an entire guide on how to write your own anti-cheats, the correct way, and even went over why certain things are good and why others are bad.
This is true, Network Ownership allows the character to be used by the client.
You cannot set the Network Owner to the server, because this will cause delayed movement.
However, your speed anti-hack can stop flying.
So maybe, there are benefits.
Also, ping checks are not as useful.
And you can easily get ping from a player by using Player:GetNetworkPing
Btw, do not use RemoteFunctions.
RemoteFunctions can cause the server to error or stop working.
(More info here)
You also need to focus on the “non-physical” hacks.
Which include Hat bypass(Moving hats around to potentially make an inappropriate images), Permanent Death Bypass(Which is used for reanimation) ,and Humanoid Removal(Which can be used for god mode).
Creating
FE++ is a good example of a “non-physical” anti-exploit.
(Also if I’m wrong with anything please notify me )
This does not rely solely on the client. Additionally, the anti-cheat memory check only activates when the window is minimized, it disables once the window is re-focused. Things such as ping and memory checks can only be done on the client, due to Roblox restrictions.
looking at your code again, I can see the speed check doesn’t rely on the client, however the memory check definitely won’t work on most exploits, and the ping check relies on asking the client for information (you don’t even account for the possibility the client overrides the invoke callback, with your current code, the exploiter can completely bypass it by overriding this and either never returning, causing it to stop working for all players, or return fake information)
My advice would be to stop trying to focus on preventing exploits from the client, and rather, focus on preventing exploits based on their visible effects as seen from the server’s perspective. And also if you absolutely must have that ping check that asks the client for information, redesign it in such a way that the request can timeout after a certain period of time (like half a minute) to stop the check being disabled for all players as a result of the exploit.
On another note, your “screenwatch” ability won’t work if the exploiter fakes information being provided to it by their client, but I don’t imagine that one is as significant.
The ping check is not made to stop script-based exploits, it is instead made to stop lag switching, or toggling your internet connection (this can be done via third party software or just disconnecting and reconnecting to internet). Lag switching can be done in combat games to freeze players, shoot them, reconnect, and deal damage. This is made to fix that.
Additionally, I wrapped the RemoteFunction in a pcall on the server, for error handling.
Unfortunately, a pcall in this event does nothing to help your case. As far as I can see, your entire while true do loop will be halted until the RemoteFunction returns, regardless of the pcall. In fact, you shouldn’t even be placing this code inside of a while true do loop to begin with, this should be placed inside of something that won’t be permanently halted in the event the client messes with the callback function on it’s end to make it wait indefinitely.
I’d suggest using RunService.Stepped or some other RunService step event instead to prevent this case from ever occurring. I was well aware the ping check isn’t focused on stopping exploits from the client-side, which is why my criticism of it was more focused on how easy it was to bypass it due to this critical flaw in its design.
I have nothing against ping checks either, they are a perfectly valid and good means of preventing the exploits you mentioned as long as they don’t have such critical flaws in their design.
It can be spoofed using hookfunctions, can raise false positive
If you hover over the link you will see the actual link lol
I just need to memorize the links lol
Yup; okay lets not derail this conversation now lol
We’ll see
In his case, the ping check cannot raise a false positive or be spoofed because it isn’t meant to make sure a player’s connection speed is within a certain range, it is meant to identify when a player is using a lag switch to simulate being completely disconnected from the server temporarily, and I highly doubt anyone who would play Roblox has internet bad enough to trigger an anti lag-switch check.
The DevHub only mentions that the method can only be called on the LocalPlayer
when used in a LocalScript
, meaning it can’t be called on other players when used in it.
“For client-side LocalScript
s, this function may only be called on the LocalPlayer
.” Player:GetNetworkPing (roblox.com)
If it can’t be used from a (Server) Script (Studio’s down so I can’t test it right now), the DevHub page should be updated to note this.
This is a misunderstanding of the wording there. That actually tells you that when it is used on the client, the client can only get its own ping, and no other player’s, but the server can get the ping of any player.
Please explain to me how the client can magically fake a perfectly fine connection, whilst at the same time, intentionally causing their connection to have a temporary lag spike using a lag switch? I am trying to emphasize that unless this is magically possible, then you cannot “spoof” an anti-lag-switch check, which is precisely what he is doing here.
If :GetNetworkPing was run on the client, I believe an exploiter could hook it to always return the same value, which I think was what @CodedJer meant.
this isn’t what the ping check in this anti cheat is doing to begin with, it sends a request to the client and sees how long it takes the client to respond to the request. This cannot be spoofed by people using lag switches (the people the ping check is intended to catch) because a lag switch for the most part, completely blocks any requests coming from the server or being sent to the server in order to simulate a large lag spike.
Don’t you know that anything on the client can be spoofed? literally everything.
Thats what I’m saying! and also everything on the client can be spoofed.
Analysis of the source code isn’t required to conclude that this (like any other public / non-game-specific) “anti-cheat” is not suitable for use in production or any practical environment outside of a .RBXL file rotting in your home directory. Systems to prevent or mitigate exploiting must be game-specific, as they have to account for game mechanics and the attack surface of implementations (such as sprinting, teleporting, weapons). They must also compromise between being able to detect broad ranges of cheats and remain accurate enough to prevent false positives.
That being said, simple code review immediately brings out both design issues and bypass vulnerabilities in the few existing “checks”.
The ping check, to start with, is fairly redundant. No game is supposed to implement a system to punish a player specifically for having high latency or a period of no connection. This is not just because players would inevitably trigger this check, which makes it a bad idea in the first place. The underlying design problem is targeting latency instead of the broader problems that “lag switches” cause, which depends on the game, but can often be: “noclipping” through objects or avoiding obstacles, abusing client-side hit registration to damage players while being otherwise invulnerable or at a different location, etc.
This reinforces the statement that anti-exploiting systems must be game-specific. With this check you are only creating false positives while ignoring all other vectors of attack.
On top of the design flaw, the ping “check” is vulnerable to being completely bypassed due misuse of InvokeClient. A pcall is in place to prevent the server from throwing an error in the case of the client throwing one or disconnecting before returning, but this does not address the issue that the client can cause the server code to yield infinitely by never returning, with something simple like this:
RemoteFunction.OnClientInvoke = function()
while wait() do end
end
This, of course, can be fixed by using tasks and a proper timeout (or switching to a RemoteEvent-based system), not that it would negate how useless this is. Keep in mind that this “check” is meant to just “rubber band” the player in case of a loose connection. The player character can still momentarily arrive at an otherwise inaccessible location: Ex. a badge giver, button or other type of restricted area. This would also not mitigate any issue relating to using lag-switches with insecure client hit registration weapons and such. Instead of figuring out the rest of the infinite issues this check has, it’s easier to conclude that it’s useless and will never prevent any kind of practical exploit, and would instead introduce false positives.
The speed check relies on HumanoidRootPart to provide the character’s position. Due to the player character’s network ownership being set to the player’s client, an exploiter can potentially freeze, detach or remove (this applies to any part in the character model) HumanoidRootPart entirely (in a way that replicates to the server), thus bypassing this check. Further additions and checks need to be added to prevent illegal modifications to the character, if you wish to stick to this methodology. “Lee-way” is also added to the maximum allowed travel distance, which opens up a path to a lower-priority vulnerability which allows an exploiter to have higher-than-average movement speed while avoiding detection.
The API for this check allows a player to be excluded (ex. for teleports) which opens up vulnerabilities where an exploiter can use this exclusion time to teleport to an inaccessible location. A potential fix for this is to implement checking for server-sided teleports by using the Changed event on the Position or CFrame properties, as it only fires when this value is manually changed.
Another vulnerability is caused by the “check’s” long-interval-based distance checking instead of calculating a path, which can allow for an exploiter to travel at illegal speeds as long as they stick close (running in a circular motion, for example).
The “check” introduces false positives due to lack of proper implementations as well, such as:
- Cases where speed is applied only momentarily and reset before Humanoid.WalkSpeed is indexed (Lack of a journaling or caching system for all player speeds during a given interval and their timings in order to calculate an accurate maximum allowed path distance)
- Cases where physics forces (explosions, doors, slings, etc, moving platforms) or force instances (LineForce, BodyVelocity, etc.) give the character speed above what would be allowed by the maxTravel number, which only factors in Humanoid.WalkSpeed indexed at a slow interval.
- Cases where the player is falling off of a taller object, attaining a speed from gravity higher than what maxTravel allows
… and many other, which aren’t hard to figure out, but would turn this post into an entire book.
I refuse to comment on the client-sided “checks” as they can always be bypassed regardless of complexity or quality of implementation. Generally speaking, client-sided anti-exploit systems are a flaw on their own and should never be something you waste time on.
This post only has two points: to give insight into the current vulnerabilities in case you want to continue this as some “for-fun” personal project, and to hopefully discourage users from ever publishing or using such public / non-game-specific anti-exploit systems, as their only purpose is to cause headaches when dealing with false-positives and to give a false sense of security.
This post may have quite a few stylistic mistakes as I wrote this fairly quickly and without much organization, so feel free to point them out or otherwise respond to the content.