I've found something concerning with a custom shop system I'm working on. The purchase event is trusting the total amount sent from the client instead of calculating it server-side.
Here's the basic event structure:
local QBCore = exports['qb-core']:GetCoreObject()
RegisterNetEvent('shop:buy', function(itemName, quantity, total)
local player = QBCore.Functions.GetPlayer(source)
player.Functions.RemoveMoney('cash', total)
player.Functions.AddItem(itemName, quantity)
end)The issue is that a modified client can call this event with a lower total than what the item actually costs. The server validates the item name exists but then removes whatever total the client sends over. This means players can purchase items for less money than intended.
I can reproduce this by calling the event directly with a manipulated total value. The normal UI purchases work correctly since they calculate the total client-side based on actual prices, but there's nothing preventing a modified client from sending a different total.
Is there a standard approach for validating purchase totals server-side? I'm thinking I need to fetch the actual item price from server configuration and compare it against what the client sent, but I'm not sure about the best way to handle this in QBCore.
PhantomBlade · 28/08/2026
Sign in to reply.