How to handle a secure attribute changed replication?

In my game, I wanted a way so I can easily locally change an attribute of an object and replicate that change onto the server, however I wanted this to be easily done, I would use this module script and then I would call it locally first and only be called once, this module script has a function, AttributeChangeSetUp, which takes in an object and an attribute to replicate as a parameter, it will then call a remote function which will be called whenever that attribute is changed on the client.

local RS = game:GetService("RunService")
local ER = {}
if RS:IsClient() then
	local aR = game.ReplicatedStorage:WaitForChild("remotes"):WaitForChild("attributeReplicate")
	function ER.AttributeChangeSetUp(a, attributeName)
		assert(a, "Object is missing")
		--The only form of security is that this attribute must exist first
		if a:GetAttribute(attributeName) == nil then
			warn("The object "..a.Name.." has no attribute "..attributeName)
			return
		end
		a:GetAttributeChangedSignal(attributeName):Connect(function()
			aR:InvokeServer(a,attributeName, a:GetAttribute(attributeName))
		end)
	end
	
end
return ER

I feel like there is a major security issue with this code, but I can’t really put my finger on it. What methods should I use to make this more secure, alternatively, what are different ways that I can do this?

1 Like

This does have huge security problems and functions like these are how game-breaking exploits are made, since without checking, you’d be allowing any exploiter to replicate any object and attribute. To give some security, I think you should add some checks for what the remote function is allowed to change the attribute of (and kick the player if they try to change something else or smth). Making sure the attribute values are within realistic values would also definitely be something to check.

1 Like

This entire system is a major security issue. The server should be the single point of truth; giving the client authority to control this can cause a multitude of problems from race conditions (assuming clients can manage the same attribute on the same object) to exploiting (modifying game critical values).

You should base off the need for the client to give something to the server to replicate on the specific system that you’re trying to accomplish over making a catch-all module for this.

1 Like

I guess from the thread there is no good way of doing what I want without sabotaging my security. I’ll remove the code for now and later see if I could think up a better method, I don’t think for posterity keeping this around for convenience is worth it. Thanks.

Ok I took out the code entirely from the module script and made it a local function inside of a local script. This way people can’t just require the module script and get access to the module functions. Is this any better?

The problem isn’t where you put it, the problem is the code itself; it shouldn’t exist at all. Additionally there’s not enough information on the circumstances in where this would be applicable. What’s your exact use case for client authoritative attribute replication?

I have a game where I have a module script associated with a class of a character in game. This module script is called locally, previously I had a server script handling everything but that yielded some bad performance, especially with tweening. I’m trying to see to what extent can I get away with only having a single locally required module script to code my character.

In this case a character model I am coding has a part which deals damage, like a sword, however I wanted it to be toggleable, so that the part that damages doesn’t hurt other players when the play isn’t attacking. Normally I would just have a remote function which simply changes the “enabled” attribute of the damage part that I call locally, but I wanted to find a more convenient way of doing this.

That’s fine but the server should ideally still be authoritative in some manner. It should know what the player is using and when it’s appropriate to determine that their character is allowed to deal damage or not. If you allow the client to be authoritative of their attacking state they can leave it permanently on and inflict damage in cases where they shouldn’t be.

The server can and should still be responsive to player input or at least have a way to determine if a client’s request is illegal or not but you don’t need to have the client being authoritative of an attribute for that. Something you could look into, assuming you don’t have animation cancelling, is the server enabling damaging when the client sends input and then using a timer to disable damaging after the time in which the animation is meant to last for. Optionally offset the timer a bit to add an attack cooldown so the client can’t chain damage requests and pseudoinfinitely enable damaging.

Is it a good idea to generate a verification code on a local script, and send that information to the server storage, and only allow replicatable changes to the server if, and only if, the client is able to give the correct verification code?

No. That’s security through obscurity which is not real security. Code-based verification for remotes has been discussed frequently on the forums, it’s not a real validation strategy. You need to make attribute control specific to your system. A catch-all module will not work appropriately here.

1 Like