Example on how to improve security against a lesser known exploit(different datatypes)

Hello there. I would like to talk about a flaw in client-server communication people tend to have and how to fix it.

EDIT: ALSO CHECK FOR THE PARENT OF THE OBJECT THIS CAN CAUSE OTHER ISSUES!!

This is a quick example of bad security.


BuyRemote.OnServerInvoke = function(plr,item)

    if plr.Cash.Value >= item.Cost.Value then

        plr.Cash.Value -= item.Cost.Value

        local bought = Instance.new("BoolValue")

        bought.Name = item.Name

        bought.Parent = plr.BoughtItems

        return true

    end

    return

end

You most likely do not know how this can be bad for your game security. Well I will explain.

BuyRemote.OnServerInvoke = function(plr,item)
	if plr.Cash.Value >= item.Cost.Value then

You see how it checks for a item cost? Here is an example of how you can get past this from the client.

BuyRemote:InvokeServer({["Cost"] = {["Value"] = 0},["Name"] = "Pistol"})

This is due to the server not type checking for in this case a table.

You can easily fix this with a simple solution! Look what I do here.

BuyRemote.OnServerInvoke = function(plr,item)
	if typeof(item) ~= "Instance" then return end
	if plr.Cash.Value >= item.Cost.Value then
		plr.Cash.Value -= item.Cost.Value
		local bought = Instance.new("BoolValue")
		bought.Name = item.Name
        bought.Parent = plr.BoughtItems
		return true
	end
	return
end
if typeof(item) ~= "Instance" then return end

In short, this line makes sure the item argument is a instance as in this case, it’s meant to be an instance. Checking for if the datatype is the correct type can fix a lot of issues.

Please reply if you have any questions. I may or may not get back to you.

4 Likes

Would i have to do this when i access a module script from a variable? I usually store all of my item data in a configurable module and have my server scripts require it.

1 Like

Depending on how the shop system works modules are usually ok.

1 Like

This still doesn’t quite solve the issue. Allowing the player to send arbitrary data at all such as instances can lead to tricky scenarios where they can send invalid instances that meet the properties or tree that the server expects and still produce unintended results.

The better solution would be for the server to have an exclusive copy of the information, whether in a table or a specific place in the game tree, and have the player send a string that indexes it.

6 Likes

This. What I do is send to the server: { Option, ItemName, Quantity }

For example: { “Buy”, “Gold Sword”, 1} or {“Sell”, “Bronze Sword”, 3} and then have the server check if the player has the item(s) if selling, or can purchase the item if buying.

1 Like