What's the best way to secure this remote event from exploiters?

Hi, I’m working on an inventory system that uses a remote event to signal to the server when a tool needs to change parent objects.

Now, the issue with this is that the server takes an item and puts it in a given place.

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Remotes = ReplicatedStorage.Events.Remotes
local InventoryEvent = Remotes.InventoryMove

InventoryEvent.OnServerEvent:Connect(function(Player: Player, Item: Tool, Parent)
	Item.Parent = Parent
end)

I have very little experience with anti-cheat and have rarely ever attempted to add any level of security to my client-server communication, so correct me if this isn’t a vulnerability, but I feel as if this is unsecured. An exploiter could fire this event from the client and effectively destroy anything they want, or at least that’s what I imagine would be possible.

Thanks.

1 Like

Lot’s of stuff to do to make a more secure system:

  • simple rate limiting on inventory moves and other related inventory processes, mostly to avoid duplication
  • create validity checks for the ownership of certain tools. You can assign certain values to the tools such as OriginalOwner or LastValidOwner to make a sort of track record/history for where the tool has been. (“Owner” also refers to potential containers)
    You can also verify the ownership of the tool:
if (playerBackpack and Item.Parent == playerBackpack) or (playerCharacter and Item.Parent == playerCharacter) then
		-- Validate the intended Parent location
		if Parent == playerBackpack or Parent == playerCharacter then
			-- Only allow moving between valid inventories/containers (Backpack <- -> Character)
			Item.Parent = Parent

you can never eliminate the possibility of exploiting with one or two things but adding as many obstacles as possible and limiting the amount of lanes an exploiter can use is your best route :smiley:

Thank you for your response.

I’m not really concerned that someone could duplicate items using exploits, as I already have a system in mind to prevent that.

I’m concerned that someone could fire that event to set someone or something’s parent to nil and destroy it, or to something else to cause problems.

An exploiter could potentially move any tool to any parent, including destroying items or placing them where they shouldn’t be

Steps if you want to keep the inventory management on the client:

  • Make sure the item is a tool and a valid one that hasn’t been modified.
  • Ensure the player actually owns or has access to the item they’re trying to move.
  • Verify that the new parent is a valid location (e.g., player’s backpack, a specific container).

OR
Instead of sending the tool, send the name of the tool, so the server can scan a tool list on the serverside to get it for them and set its parent, also do the steps from before.

Just a word of advice, Keep the inventory management on the server, not the client.

1 Like

It really depends on the purpose of this event and what its constraints are going to be. For example, if you only want players to be moving an item from their backpack to some folder (example). You would have to validate the player and the parent to be a valid source and destination.

1 Like

Thank you for the in-depth response.

You probably have the best overall solution, but I’m going to go ahead and put mine, but still give you the solution.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlayerService = game:GetService("Players")

local Remotes = ReplicatedStorage.Events.Remotes
local Assets = ReplicatedStorage.Assets.Containers

local InventoryEvent = Remotes.InventoryMove
local ContainerEvent = Remotes.CreateContainer

ContainerEvent.OnServerInvoke = function(Player: Player, ContainerName: string)
	local Container = Assets:FindFirstChild(ContainerName):Clone()
	Container.Parent = Player.PlayerGui:WaitForChild("Main_Inventory")
	
	return Container
end

InventoryEvent.OnServerEvent:Connect(function(Player: Player, Item: Tool, Parent)
	local FoundPlayer = Item:FindFirstAncestorWhichIsA("Player")
	
	if Item:IsA("Tool") then
		if (PlayerService:GetPlayerFromCharacter(Item.Parent) == Player) or (FoundPlayer and FoundPlayer == Player) then
			Item.Parent = Parent
		end
	end
end)

Very primitive, but I’m effectively just making sure that whatever modifications are made are only to the person trying to make them and their character/player, as well as it’s only the tool. Not sure how well this will work but I hope it does and/or maybe it’s useful for someone else.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.