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
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
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.