Skip to content

How FXScan works

FXScan is a static analyser for FiveM resources. It reads the code in an archive you upload, follows how data moves through it, and reports the paths that look like a backdoor, remote code execution or an exploitable net event - without ever running that code. This page explains how it reaches a finding, where it can be wrong, and what happens to your files.

The scan, step by step

  1. Archive validation. Before anything is extracted, the ZIP is checked for path traversal, symlinks, suspicious compression ratios and entry counts. An archive over a size or file-count limit is rejected, not partially analysed.
  2. Safe extraction. Entries are streamed against hard byte budgets, so a ZIP bomb stops mid-flight instead of filling a disk. Nested archives are reported and never unpacked.
  3. Manifest discovery. Every resource in the archive is found from its fxmanifest.lua (or legacy __resource.lua). The manifest is parsed declaratively - it is never executed - so each file is known to run on the server, on the client, or not at all. That matters: a load() in a client script is a different risk from the same call on the server. If you want to understand the manifest itself, Titan Software has a complete fxmanifest.lua guide.
  4. Syntax trees and data flow. Lua, JavaScript and TypeScript are parsed with tree-sitter into real syntax trees. The analyser then follows untrusted values - HTTP responses, net event arguments, chat command input - through assignments, calls, tables and decoders to dangerous sinks such as load, ExecuteCommand or a money grant.
  5. Evidence. Each finding carries the file, line and code excerpt, and where a path was proven, every hop of the chain with a confidence value. The report combines findings into a safety score from 100 (nothing suspicious) down to 0, weighted so that one proven remote-execution chain outweighs many low-confidence warnings.

How detection rules work

FXScan currently applies 66 rules (rule set 2026.02.1) across eight categories: remote code execution, command execution, unsafe network events, exfiltration, persistence, hardcoded secrets, obfuscation and suspicious logic. Every rule has a unit test with a fixture that must trigger it and a fixture that must not. The complete list, with what each rule detects and how to fix it, is in the detection rule catalogue.

The design principle is that single signals are not findings. A lone PerformHttpRequest, a lone Discord webhook, a lone RegisterNetEvent or a lone load() appear in thousands of honest resources. What makes code malicious is the combination - an HTTP response that reaches load(), a client-sent number that reaches addMoney - and that path is what a CRITICAL finding means. The anatomy of a FiveM backdoor walks through the most common chain in real Lua.

False positives

Some legitimate code is shaped like malicious code. A framework that loads its own plugin files uses load; a server that sends player identifiers to its own analytics endpoint looks exactly like exfiltration, because intent is not something code reveals. FXScan handles this in three ways:

  • Confidence and severity are separate. A pattern that is merely present scores lower than a proven data-flow path from untrusted input.
  • Evidence is always shown. A false positive is usually obvious within seconds once you can see the chain; so is a true one.
  • Suppressions. A finding you have reviewed can be suppressed. The judgement is stored against the finding's fingerprint, so it applies to the same code in later scans, and each report states how many findings it left out.

What static analysis cannot see

  • Absence of a pattern is not proof of safety. A clean report means no rule matched. A resource can be malicious in a way no rule covers yet.
  • Runtime-assembled behaviour. Strings built from convars, player data or the date are flagged by shape where the shape is suspicious, but their value cannot be known in advance.
  • Deep indirection. Data-flow analysis has a budget; a payload routed through enough layers can exceed it.
  • Unreadable content. Escrow-protected .fxap files are encrypted, and native binaries or precompiled Lua bytecode are not source. All of them are recorded as unreadable in the report rather than silently skipped.

The longer version is what a security scan cannot tell you. For protecting a server against what static analysis cannot catch, see Titan Software's FiveM server security guide.

What is uploaded and stored

You upload a ZIP archive. FXScan stores it so the scan can run and so findings can be re-examined, then deletes it automatically:

  • The uploaded archive: 7 days.
  • A sanitized archive, if you accept proposed patches: 7 days.
  • The report - file metadata, findings, code excerpts and extracted indicators such as URLs: 30 days on the free plan, up to 90 days on paid plans.

Reports belong to the account that created them and are private by default; nobody can open one by guessing its link. Sign-in is handled by Titan Auth, so FXScan stores no passwords. Uploaded code is not shared, sold or published. The full detail, including the processors involved and your rights, is in the privacy policy and the data processing agreement.

FAQ

Does FXScan run the code I upload?
No. Files are read, hashed and parsed into syntax trees. Nothing in the archive is executed or evaluated, the manifest is parsed rather than run, and no URL found in the code is ever requested.
Why did a legitimate resource get a finding?
Because some legitimate code has the same shape as malicious code - for example a resource that loads its own plugin files, or sends player identifiers to an analytics endpoint you own. Every finding shows its evidence so you can judge it, and you can suppress a finding you have reviewed; the report then says how many findings it left out.
Does a clean report mean a resource is safe?
No. It means none of the rules matched. Static analysis proves that a pattern is present, never that every bad pattern is absent.
Who can see my upload and report?
Only your account. Reports are private by default; you can create a read-only share link and revoke it at any time.
How FXScan Works: Static Analysis, Detection Rules & Limits | FXScan