Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How do i protect my remote event ?

How do i prevent hackers from accesing to remote event ?

2 comments

0

By placing it in ReplicatedStorage. Or you can add a extra security layer by setting it's parent to ServerStorage and use a 'RemoteFunction' to require the remote.

4

Wth no

2 answers

✓ Accepted answer

Client-Server Game Architecture

The first page of that article gives great guidelines for how you should structure communication between the clients and the server.

There are tips and tricks to "hide" your RemoteEvents from exploiters, however you should not rely on such things. The best course of action to protect your game, is to learn about the client-server model and remove bad practices from your code.

Exploiters access the game, like all players, from their respective client. As long as FilteringEnabled is turned on, you are able to stop changes made client-side from automatically reflecting to the server, except for internal ones that ROBLOX has permitted.

As you pointed out, it is possible for exploiters to fire your RemoteEvents from the client to the server. So what do you do?

Don't trust any client. Every player is a potential exploiter, so every message sent from the client should be sending specific input, and not given direct power to make real changes to the game.

Here is what you shouldn't do.

Client:

local players = game:GetService("Players")
local player = players.LocalPlayer
local rep_store = game:GetService("ReplicatedStorage")
local kill = rep_store.Kill or rep_store:WaitForChild("Kill")  --RE

player.Chatted:Connect(function(msg)
	if player.Name == "amandatest" then
		local cmd, target = msg:match("(%a+)%s(%w+)")
		print(cmd, target)
		if cmd == "kill" then
			kill:FireServer(target)
		end
	end
end)

Server:

local players = game:GetService("Players")
local rep_store = game:GetService("ReplicatedStorage")
local kill = rep_store.Kill or rep_store:WaitForChild("Kill")  --RE

kill.OnServerEvent:Connect(function(player, name)
	local character = workspace:FindFirstChild(name)
	local player = players:GetPlayerFromCharacter(character)
	if player then
		local humanoid = character.Humanoid
		if humanoid.Health > 0 then
			humanoid.Health = 0
		end
	end
end)

Now lets talk about why this is bad.

  • You shouldn't have a RemoteEvent that has a sole purpose of killing/kicking or performing any action directly on any player, it is exactly what exploiters are looking for.

  • Handle chat commands on the server. This way you can check against a hidden lists and access can't be spoofed.

  • The sever should be the one checking which client is sending the input, the type of input, and if the combination is authorized in the current game state.

  • If you are sending information from a client to the server, it should almost always be raw input and not anything else. The server should be in charge of handling that input, so no matter what it is, it won't break any part of your game.

Enjoy an example below which shows a safer (and more comedic) use of a RemoteEvent.

Client:

local uis = game:GetService("UserInputService")
local rep_store = game:GetService("ReplicatedStorage")
local log = rep_store.Log or store:WaitForChild("Log")

uis.InputBegan:Connect(function(obj)
	if obj.KeyCode == Enum.KeyCode.G then
		log:FireServer("G")
	end
end)

Server:

local players = game:GetService("Players")
local rep_store = game:GetService("ReplicatedStorage")
local log = rep_store.Log or rep_store:WaitForChild("Log")

local debounce = {}

log.OnServerEvent:Connect(function(player, key)
	local name = player.Name
	local message
	if key ~= "G" then
		--kick exploiter/add to banlist
		print(("SERVER: falsified input, kicking exploiter[%s]. . ."):format(name))
	elseif debounce[name] then
		print(("SERVER: %s has just been debounced. Please wait a few seconds before trying again"):format(name))
	else
		debounce[name] = true
		print(("SERVER: Hey %s, you are a G. ;)"):format(name))
		wait(5)
		debounce[name] = false
	end
end)	

players.PlayerRemoving:Connect(function(player)
	debounce[player.Name] = nil
end)

Summary: use best practices, don't trust the client

Feel free to click view source and test out all my code for yourself.

3 comments

0

Static keys are a bad idea since exploiters can view events that are fired from their client.

0

It isn't intended to be a secret what keys do, in my example. It is meant to more or less represent a keybinding.

0

If they fire the RE with G, then all they have done is spent a lot of work when they could of just pressed it on their keyboard, and won't provide any inherent advantage in this example.

You can't necessarily prevent hackers from accessing your remote event as far as I know. However, you can add checks to the server script to help prevent hackers from spoofing your remotes. I'll give you 2 examples.

Say for instance, there is a remote that gives a player extra health but you only want it to be accessed by a certain player. You can do this.

whateverremotelocation.OnServerEvent:connect(function(plr)
	if plr.Name ~= "whitelistedplayer" then return end
end)

EDIT: Whoops. Forgot the other example.

Or if you have a remote that changes a part to a certain color, with the part and color in the arguments, you can prevent exploiters from spoofing your remote by doing this.

whateverremote.OnServerEvent:connect(function(plr, part, color)
if part ~= Part that the remote event is intended to change or color ~= whatever color the remote is supposed to set the part to then return end

You always must add checks to your server events. Remember, never trust the client.

Apologies if I got anything wrong, typed this very early. I'm tired.

This discussion is preserved as it was. New answers, comments, and votes are closed.