Blog
FiveM Lua Backdoors and Malicious Scripts: Spotting Hidden Code Before It Hits Your Server
FiveM Lua Backdoors and Malicious Scripts: Spotting Hidden Code Before It Hits Your Server
Backdoored scripts are not rare. They move through leaked resource packs, resold assets and even some paid storefronts that don’t audit what they list. A backdoor embedded in a QBCore job script looks identical to clean code at a glance — the malicious logic is usually three lines buried in a 600-line file, often in a callback handler that runs server-side with full access to your database and player data. This is the manual and the tooling you need to catch it before it runs.
What a FiveM Lua Backdoor Actually Does
Understanding the attack surface makes the detection patterns make sense. FiveM’s resource system gives server-side Lua access to MySQL, file I/O, outbound HTTP, and the ability to execute arbitrary commands on connected clients via TriggerClientEvent. A backdoor exploits one or more of these channels.
The most common variants:
- Remote execution via hidden net events: A server-side script registers a net event — often with a name that mimics a legitimate framework event like esx:requestModel or QBCore:Server:OnPlayerLoaded — with no permission check. Any client that knows the event name can trigger it and run the associated callback with server privileges. The callback typically calls ExecuteCommand, execs console commands, or calls a database write directly.
- Outbound HTTP exfiltration: PerformHttpRequest is available server-side with no restriction on destination. A backdoored script can POST your database credentials, player data, or server licenseKey to an attacker-controlled endpoint on first resource start. The exfiltration fires once, silently, and leaves no obvious trace in your console unless you’re watching HTTP traffic.
- Obfuscated eval chains: Lua doesn’t have a native eval, but load() does the same thing — it compiles and executes a string as Lua code at runtime. A script that receives an encoded string from a remote endpoint and passes it to load() can execute arbitrary code fetched after you install it. The string itself is often base64 or XOR-encoded so a quick file read shows nothing suspicious.
- Timing-delayed activation: Some backdoors check a condition — current date, server population count, or a flag fetched from an external URL — before activating. This bypasses naive testing on a dev box with no players. The script runs clean for weeks, then triggers.
Manual Code Review: What to Grep For
Before installing any resource you didn’t write yourself, grep the entire resource directory. These patterns flag the majority of known backdoor techniques:
- load( — any use of Lua’s load function deserves a manual read. Legitimate scripts almost never need runtime code compilation.
- PerformHttpRequest — check every call. What is the URL? Is it hardcoded or assembled at runtime? Does it POST data? Legitimate use cases are limited to webhook notifications and licence checks.
- ExecuteCommand — called from a net event handler is a red flag unless the resource is explicitly a command-execution framework.
- RegisterNetEvent with no accompanying source validation in the handler — specifically check that the handler doesn’t call privileged functions without confirming the caller’s server ID and permission level.
- io.open, os.execute, os.getenv — file system and OS access from a game script resource is almost never legitimate.
- Strings assembled via concatenation or decoded at runtime: look for patterns like string.char(, table.concat( used to build what looks like it could be a URL or Lua code fragment.
A practical grep command that covers most of these in one pass:
grep -rn “load(|PerformHttpRequest|ExecuteCommand|os.execute|io.open|string.char(” /path/to/resource/
This won’t catch everything — particularly well-obfuscated code — but it eliminates the lazy backdoors that make up most of what’s in circulation.
Recommended FiveM scripts for your server
Automated Scanning Tools
Manual grep works for one resource. For a full server stack of 80–150 resources, automated scanning is the only practical approach. Several community tools exist:
cfx_backdoor_finder (RealSvdden on GitHub) is a Lua-based scanner that runs as a FiveM resource and flags suspicious patterns across your entire resource directory at startup. It writes results to the server console, which you can pipe to a log. The detection coverage is pattern-based, not semantic, so it generates false positives on legitimate resources that use PerformHttpRequest for licence validation — review hits rather than auto-removing them.
Mystic Backdoor Scanner (Pappu100code on GitHub) is a C++ console tool that runs outside FiveM against your resource files. It catches obfuscated patterns that in-game scanners miss because it can apply more computationally intensive analysis without affecting server performance. Run it against a full resource dump before deploying to a new server or adding a batch of resources.
Neither tool replaces manual review for high-risk resources — anything that runs server-side with database access, anything sourced from a leak site, anything you can’t read because it’s obfuscated or minified.
The Escrow Question
Cfx.re’s Keymaster escrow system encrypts resource Lua files so you can’t read them. This creates an obvious problem: you cannot manually review code you cannot see. Escrow from the official Cfx.re marketplace carries some trust because Cfx.re does audit submitted resources, though not exhaustively. Escrow from any other source — a third-party seller distributing their own encrypted files — carries zero guarantees. If you can’t read it, you’re trusting the seller completely. Budget accordingly. Scripts that handle your economy, player data or admin commands should be open-source or from a known-verified storefront. The security-focused resources at scripts-tebex.io are audited before listing; the same standard applies to anything on marketplace-tebex.io.
Network Monitoring as a Second Layer
Even after scanning, monitoring outbound HTTP from your server process catches anything that slips through. On Linux, ss -tnp shows active connections by process. A FiveM server making outbound connections to IPs you don’t recognise — especially shortly after startup or on player join — is worth investigating immediately. Set up a firewall allowlist for the outbound destinations your legitimate scripts use (Discord webhooks, your licence server, your database if external) and log everything else. An unexpected POST to a random IP is your earliest warning of an active exfiltration.
Upgrade your server — shop our FiveM scripts
When You Find a Backdoor
Remove the resource, rotate everything the server had access to — database passwords, Discord bot tokens, API keys stored in server.cfg as convars — and audit your database for unexpected admin accounts or modified player records. The backdoor has been running since you installed the resource; assume the worst about what it exfiltrated. For scripts you rely on that were backdoored, find a clean alternative through a verified source. Anything on cfxre-tebex.io ships without obfuscation on the relevant server files, which means you can read what you’re running.