Security9 min read

Securing a FiveM server: permissions, events and backups

Most server incidents are not clever hacks. They are unvalidated events, shared admin accounts and a backup nobody ever tested. Here is the practical checklist.

Written by Mira Kessler

Padlock on a metal server cabinet door

The typical server incident is not a break-in. It is a client-side event that hands out money because nobody checked who called it, and a staff account that four people share.

Never trust the client

Anything the client sends can be forged. If a resource registers a network event that gives an item, pays out money or changes a job, the server has to verify that the calling player is allowed to do that, right now, in that situation. Checking on the client is decoration; the check that counts happens on the server.

-- wrong: trusts whatever the client sends
RegisterNetEvent('shop:buy', function(item, price)
  giveItem(source, item)
  removeMoney(source, price)
end)

-- right: server decides the price and the conditions
RegisterNetEvent('shop:buy', function(itemId)
  local src = source
  local item = Shop.items[itemId]
  if not item then return end
  if not Player.isNearShop(src, item.shop) then return end
  if not Player.canPay(src, item.price) then return end
  Player.pay(src, item.price)
  Player.giveItem(src, item.id)
end)

This is also a buying criterion. When you evaluate a script, ask where the decisions happen. Server-authoritative logic is the difference between a duplication bug and a duplication economy.

Permissions belong in ACE, not in a list of identifiers

FiveM has a permission system. Use it. Grant commands to groups with add_ace, put people in groups with add_principal, and remove a leaving staff member by deleting one line. Hardcoded identifier lists inside resources are how ex-admins keep their powers.

  • One account per admin, never a shared login
  • Separate groups for moderation, development and ownership
  • Log admin actions somewhere the admins cannot edit
  • Review the list every month; it only ever grows otherwise

Database hygiene

  • A dedicated database user for the server, not root
  • The database bound to localhost or a private network, never open to the internet
  • Credentials in the server config, not in a resource you might share
  • Regular dumps, stored somewhere other than the server they came from
A backup you have never restored is not a backup. Restore one into a test database once, time how long it takes, and write the number down. That number is your worst-case downtime.

Anticheat is the last layer, not the first

An anticheat catches the obvious. It cannot fix a resource that lets any client trigger a payout. Order of work: server-side validation first, permissions second, anticheat third. Servers that do it in the reverse order stay busy forever.

Update discipline

Keep the server build reasonably current, and read release notes for the resources you run. Most exploits that make the rounds are patched long before they are used widely — on the servers that updated.

Frequently asked questions

Do I need an anticheat for my FiveM server?
It helps against common cheats, but it is not a substitute for server-side validation. Fix the logic first, then add an anticheat as an extra layer.
How often should I back up my database?
Daily at minimum for an active roleplay server, kept off the machine that hosts the server, and tested by restoring one occasionally.
What are ACE permissions?
FiveM's built-in permission system. You allow commands for a group with add_ace and assign players to groups with add_principal, which keeps access out of individual resources.