I think I have found the exploiter and currently trying to get info out of him.
Currently got so far that he is able to manipulate all number values with my unload gun event.
He is using some weird method, he told me that he is sending a table instead of my normal object value that it normally receives.
he uses something like this UnloadEvent:FireServer({idk1=idk2, idk3=idk4})
my server script is below
local function onUnloadEvent(playerQ, itemQ) -- he sends a table here
--print("unload")
spawn(function()
local player, item = playerQ, itemQ
local rs_player = game.ReplicatedStorage.Players:FindFirstChild(player.Name)
local SecurityCheck = false
if isInTable(InvSystemLocalTypes, item.Parent.Name) and item.Parent.Parent == rs_player then
SecurityCheck = true -- checked if the gun is in players inv who fired it
elseif rs_player.Status.Looting.CurrentContainer.Value ~= nil then
local selectedContainer = rs_player.Status.Looting.CurrentContainer.Value
local Inv = selectedContainer.Properties.Inventory
local virtualInv = selectedContainer.Properties.VirtualInventory.Value
if item.Parent.Parent == virtualInv then
SecurityCheck = true -- checked if the gun is in the container that the player who sent it is looting
end
end
if SecurityCheck == true then -- the weird thing is how can he pass the check
local InventoryStorageEmptySlots = 24
local InventoryStorage = {}
for _, v in pairs(rs_player.Inventory:GetChildren()) do table.insert(InventoryStorage, v) end
InventoryStorageEmptySlots = InventoryStorageEmptySlots - #InventoryStorage
local ToolbarStorageEmptySlots = 6
local ToolbarStorage = {}
for _, v in pairs(rs_player.Toolbar:GetChildren()) do table.insert(ToolbarStorage, v) end
ToolbarStorageEmptySlots = ToolbarStorageEmptySlots - #ToolbarStorage
local needToStackMore = StackInto(player, rs_player.Inventory, item ,InventoryStorageEmptySlots)
if needToStackMore > 0 then
local needToStackMore = StackInto(player, rs_player.Toolbar, item, ToolbarStorageEmptySlots)
end
end
end)
end
ps. wanted to add that he can only lower values with that
there are other events possibly having the same bypass
what currently doesn’t make sense is how can he manipulate the check to let it pass and also how can he change the object that he can change all number values in game. This script is designed to only change “LoadedAmmo” value.
Don’t know the exact details of this but a general rule of thumb is that exploiters can and will be able to manipulate remotes in any way. They can do anything with that remote a local script can do.
Its also possible for exploiters to view which remotes are fired, what their values are and such.
He cant. It is and will always be an impossibility for exploiters and client sided scripts to change server scripts directly. There must be some other variable or such that the client has access to for him to be able to change it.
yep know that, but in some weird way he can manipulate any number value through this remote.
But I am not understanding how this would be possible in anyway this is why I came here.
For starters, I don’t understand or see any code that’s changing number values.
But what I do know is that you are letting the server trust the item the client sends.
Take these lines of code for example:
local player, item = playerQ, itemQ
This makes the server trust whatever the client has sent, which is the first rule of remote events: Never trust the client. There should be a sanity check performed if your client scripts send Instances as arguments, because they can be faked as tables.
Now if I were to do:
UnloadEvent:FireServer({
Parent = {
Name = "some name",
Parent = {
Name = "some other name"
}
}
})
The server would interpret this as a valid “item” object. I’m not sure how important faking these arguments are; I still don’t know what StackInto is doing that trusts the item he’s sending. He’s most likely spied on your remote events and sent a fake table with modified info.
I don’t want to leak my whole script so i will give the part where it changes the current ammo value to 0 after creating a stack of ammo that the gun unloaded
Item.ItemProperties.LoadedAmmo.Value = 0
currently I still don’t understand how sending it as a table can bypass
if it’s a table shouldn’t it error, because it’s expecting an object value
You can just check against the typeof(item) value and make sure it’s an Instance. But you also need to check that the instance being sent is parented to the right place, of the right class, etc.
You’re better off making it so the server finds this instance itself or already has access to it somehow rather than relying on the client passing an instance reference.