Skip to content

The most common FiveM vulnerability is not a backdoor

Trusting a client-sent network event is more common than any deliberate backdoor, and it costs servers their economy. What an unsafe RegisterNetEvent looks like, and how to fix it.

2 min readFXScan

Deliberate backdoors get the attention. The vulnerability that actually drains servers is duller: a server-side event handler that believes what the client told it.

The shape of it

RegisterNetEvent("shop:buyItem")
AddEventHandler("shop:buyItem", function(item, price)
  local src = source
  local player = GetPlayer(src)
  player.removeMoney(price)
  player.addInventoryItem(item, 1)
end)

price arrives from the client. Any player can call this event with any arguments, including a negative price, an item that costs nothing, or an item they were never meant to have. Nothing in that handler is a backdoor. The author simply forgot that a network event is user input.

The exploited version is one line:

TriggerServerEvent("shop:buyItem", "weapon_rpg", -1000000)

Why it survives review

It survives because it reads like ordinary code. There is no obfuscation, no suspicious string, nothing that a grep would catch. The bug is the absence of something - a server-side lookup of the real price - and absences are hard to notice.

It also survives because it works. The shop functions correctly for every player who is not attacking it, so it passes testing.

The fix

Never accept a value the server can determine itself:

RegisterNetEvent("shop:buyItem")
AddEventHandler("shop:buyItem", function(item)
  local src = source
  local definition = SHOP_ITEMS[item]      -- server-owned price list
  if not definition then return end        -- unknown item: refuse

  local player = GetPlayer(src)
  if player.getMoney() < definition.price then return end

  player.removeMoney(definition.price)
  player.addInventoryItem(item, 1)
end)

The client now sends only which item. Price, existence and affordability are all decided server-side.

The general rule

Treat every parameter of a server-side event handler as though it were typed by someone who wants your economy. The safe pattern is:

  • the client says what it wants to do,
  • the server decides whether that is allowed and what it costs.

Any handler that grants money, items, weapons, jobs or group membership using a number the client supplied is a finding. FXScan raises these as a category of their own - eleven rules covering money, item, weapon, job and permission grants reached from a client payload - because in practice they cost more servers more money than the backdoors do.

Related reading

The most common FiveM vulnerability is not a backdoor | FXScan