I was thinking about making a good method to prevent exploiters from firing remotes and I have came to a conclusion, but firstly I need feedback from experienced scripters!
LocalScript:
local RemoteFunction = game.ReplicatedStorage.RemoteFunction
local RemoteEvent = game.ReplicatedStorage.RemoteEvent
local MyKey = RemoteFunction:InvokeServer("GetMyKey", nil, nil, nil)
-- do other stuff
Server Script:
local RemoteFunction = game.ReplicatedStorage.RemoteFunction
local RemoteEvent = game.ReplicatedStorage.RemoteEvent
local HttpService = game:GetService("HttpService")
local Checker = {}
RemoteFunction.OnServerInvoke = function(Player, Command, P_1, P_2, P_3)
if Command == "GetMyKey" then
if Checker[Player.Name] then
Player:Kick("Stop exploiting")
else
local Key = HttpService:GenerateGUID(false)
Key = string.lower(Key)
Checker[Player.Name] = {
Key = Key
}
return Key
end
end
RemoteEvent.OnServerEvent:Connect(function(Player, Command, P_1, P_2, P_3)
if Command == "SomeRandomCommand" then
local Key = P_1
if Key then
if Checker[Player.Name] then
if Checker[Player.Name].Key == Key then
-- do stuff
else
Player:Kick("Stop exploiting")
end
else
Player:Kick("Stop exploiting!")
end
else
Player:Kick("Stop exploiting!")
end
end
end)
Remote keys never work. Exploiters just need to hookfunction on FireServer/InvokeServer and they can always get the key that way since the client is the one sending it
Then don’t send the key from the client lmao. One way to do this is to encrypt the key on the client, send it, and then decrypt it on the server. Then the exploiter would have to know the key used for the encrypting/decrypting and they encrypt/decrypt code. They could decompile the local script but I recommend obfuscating it so it is harder to find the code (still possible). Either way, the exploiter would still be able to get the remote key but it would be very hard with this method and they would probably give up lol. I recommend server-side sanity checks instead of remote keys but a combination of both is great.
An system of this sort is unnecessary overhead and a waste of time to add, since it doesn’t provide any actual security.
Your time would be better spent validating the remote events sent to the server, to make sure all parameters are in range, and that they are being sent in the correct context.
The system you show above would kick a lot of players incorrectly if you just added it as-is. For example, if you forgot to clear Checker[Player.Name] on player removing, anyone who reconnects to a server they’ve already been on would be kicked for exploiting. For session tables, it makes more sense to use the Player object itself as the key, not Name or UserId.
Yes, but it requires MUCH more work to get the key (deobfuscating the local script [I recommend using WallySecure {or perth scripting utilities now i think lmao} to obfuscate {free}]). You’re basically asking the exploiter to deobfuscate wallysecure (which hasnt been done and its been like 6 months since it came out). Yes, it is still possible but just very unlikely. You should also add server-side sanity checks even if they do get your remote key.
I’m not sure why you think deobfuscating any of the scripts would be necessary. Exploiters will try easier ways first, like wireshark or memory peeking (or even just hooks into the Lua to get the output), to just inspect what’s being sent with the legitimate remotes and spoof it. It’s not always necessary to be able to send totally arbitrary data, a lot of exploits can be done by sending well-formed remote events at the wrong time.
Sorry, I don’t understand what Wireshark or memory peeking do. Also, what does “hook into Lua to get the output” mean? Can you explain more please, I don’t understand?
Using WireShark to inspect the network packets being sent by the Roblox client. Or using memory view/edit tools (like debuggers or CheatEngine) to monitor what values are changing in memory when certain things are done in game, to find out how to read script-generated values right out of raw memory.
Putting hooks into Lua generally involves injecting “pass through” functions into the call Lua stack for the purpose of reading what is being sent to functions and returned by them more easily than peeking at raw values in memory.
It’s probably worth noting too, that if your RemoteEvents are properly validated and rate-limited, they are probably not what will be exploited in your game. The most disruptive client exploits are generally exploiting replication behaviors that are not related to RemoteEvents, like things about your local Character that replicate client-to-server, or things that Roblox has allowed to replicate for some legacy compatibility reason.
Also worth mentioning, is that security through obscurity is sometimes worse to have in practice than no security. And certainly worse than opaque, server-side-only security. Why? Because for some exploiters, seeing an obvious anti-exploit system in client code can be more of a challenge than a deterrant. It can make your game more fun and rewarding to exploit.
Damn, thats complex. So they could see that I am decrypting the key just by looking at packets sent by the roblox client? I have also heard of some custom exploit function that allows you to see all the local variables and their values (no complex stuff like wireshark or whatever, something like getgenv or something similar)
I would reccomend trying to hide your anti cheat. For example if you have a localscript that encrypts a key or something rename it to something already in starterplayerscripts and delete the other one so it looks like it was made by roblox and they wont bother looking at it. Another example is in my remote key test place where I hid a remote function in replicatedstorage by renaming it something that was already in there and deleting that thing.
EDIT: I like having security through obscurity and normal security (like server side checks)