FiveM implements a security sandbox for resources to ensure stability and prevent malicious code execution. This document describes the restrictions and allowed APIs within this sandbox environment.
All file system operations support two types of paths:
@resourceName/path/absolute/path/to/resourceResource mount paths are recommended as they're cleaner and more portable.
The io.readdir() function returns a directory handle:
-- Using mount paths (recommended)
local files1 = io.readdir("@myResource/")
local files2 = io.readdir("@myResource/assets")
-- Using absolute paths
local files3 = io.readdir("/absolute/path/to/resource")
local files4 = io.readdir("/absolute/path/to/resource/assets")
local files = io.readdir("@myResource/")
for file in files:lines() do
print(file) -- Process each file
end
files:close() -- Not required, but best to do so
-- Using mount paths (recommended)
local file1 = io.open("@myResource/data.json", "r")
-- Using absolute paths
local file2 = io.open("/absolute/path/to/resource/data.json", "r")
-- Available modes
"r" -- Read
"w" -- Write
"a" -- Append
"+" -- Create
Blocked operations return error code 13 ("Permission denied").
The SaveResourceFile native function follows these same rules.
New time measurement functions are available:
local nano = os.nanotime() -- Nanosecond precision
local micro = os.microtime() -- Microsecond precision
local delta = os.deltatime() -- Time difference
local tsc = os.rdtsc() -- Read Time-Stamp Counter
local tscp = os.rdtscp() -- Read Time-Stamp Counter and Processor ID
-- Blocked with "Permission denied" (code 13)
os.execute("command") -- All commands blocked
io.tmpfile() -- Temporary files blocked
io.popen(command .. resourcePath .. path .. suffix) -- Only emulated 'ls' and 'dir' allowed
-- Limited functionality
os.getenv("os") -- Returns "Windows" or "Linux"
os.setlocale() -- Returns current locale, cannot modify
-- These operations remain available
load() -- Not blocked
Enabling resource modifications or filesystem permissions can be dangerous if misused. Only enable these for resources you trust completely.
To explicitly allow a resource to write files to another resource, use the add_filesystem_permission configuration:
-- Allow resourceA to write files to resourceB
add_filesystem_permission resourceA write resourceB
This override grants full write access to the target resource and bypasses the default cross-resource write restrictions.
To restrict ConVar access to specific resources, use the add_convar_permission configuration:
-- Restrict reading of a ConVar to specific resources
add_convar_permission resourceA read some_convar_name
By default, ConVars are readable by all resources. Once a ConVar has at least one permission configured, it becomes restricted and only explicitly permitted resources can access it.