Security and permissions
Players install mods from strangers and join servers that send mods to them. The modding system is built so that a mod can only do what the game offers through its API, and only what the player allowed.
What no mod can do
- Run native code. Packages containing
.dll,.exe,.cs,.js, scripts for other shells and similar files are refused as a whole. There is no way to load compiled code of any kind. - Touch the file system. A script reads its own files (read-only) and its own storage, and nothing else. Paths cannot climb out of the mod (
../), use drive letters, or reach device names. - Reach the game's internals. Only the functions in the reference exist. There is no reflection, no
debuglibrary, noloadorloadstring, and objects returned to Lua expose only their documented fields. - Use the internet freely. Only through
http, only over HTTPS, and only to sites the player agreed to by name. - Freeze the game. Every call has a time budget. Endless loops are stopped, and a mod that keeps hitting the limit is stopped for the session.
- Change another mod. Mods have separate globals and cannot modify each other's objects or events.
- Keep changes after it stops. Everything a mod created or changed is removed or restored.
Permissions
A mod lists its permissions in mod.json. The full list, with risks, is on the permissions reference.
| Risk | Examples | What the player sees |
|---|---|---|
| Low | ui, audio, net, players, building, devtools, video | Nothing. Granted by declaring it. The effects stay inside the mod's own panels, sounds and messages. |
| Medium | world, ui.game, input, camera, building.edit, building.overlap, building.physics, building.kinetics, players.teleport, scenes | Listed before the mod first runs. The player allows or declines. |
| High | building.limits, http:<site> | Listed prominently, with an explanation of why it is risky. |
In Mods, switching on a mod that needs consent opens its list of permissions, each with what it allows and a dot for its risk; Allow grants them and Don't allow switches the mod back off. The player's decision is remembered for that mod. If a new version asks for more or different permissions, the player is asked again. Revoke consent in Mods takes the decision back and stops the mod. See Installing mods for the player's side.
When a script calls a function its mod has no permission for, the call fails with a message naming the permission: 'you.mod' needs the 'world' permission to create objects. Declare it in mod.json under "permissions". Repeated refusals count as strikes (see time budgets).
Choosing permissions
Ask for as little as you need. A mod that only needs ui and audio installs without a single question. Players trust those more, and they are the mods servers are happy to run.
Internet access
"permissions": ["http:api.example.com", "http:*.scores.example.org"]http.get("https://api.example.com/top?n=10", function(response)
if not response.ok then return log.warn(response.error) end
local scores = json.decode(response.body)
end)Rules the game enforces for every request:
- HTTPS only, on the standard port (443).
- Named sites only. The address must be a name the mod was granted.
*.example.orgcovers subdomains, notexample.orgitself. IP addresses are refused. - No local networks. Names like
localhost,router.lanandprinterare refused, and so is any name that resolves to a private, loopback or link-local address, so a public name cannot point into the player's home network. - No redirects. A granted site cannot forward the request to a site that was not granted.
- Limited headers. Only
Accept,Authorization,If-None-MatchandX-…headers. Cookies are cleared before and after every request, so no session is sent along. - Limited size and rate. Bodies up to 1 MB, answers up to 4 MB, 20 seconds timeout, 4 requests at once and 60 a minute per mod.
- Steam's services can never be contacted, and the game can reserve its own the same way.
The site you contact sees the player's IP address. The permission prompt says so.
Mods from servers
When you join a server:
- The server announces each mod's id, version, size, permissions and a SHA-256 content hash of its files.
- Your game shows you the list, with each mod's permissions and risk, before downloading anything. Nothing is downloaded or run without your agreement, and a list with a high-risk mod needs an extra tick before you can join.
- Every downloaded file is checked against the announced hash, and each mod must ask for exactly the permissions that were announced. A package that does not match is thrown away.
- Before anything runs, the downloaded scripts are checked for code that hides what it does, such as packed code or reaching for functions the sandbox removes. If something turns up, you are asked again.
- Downloaded mods live apart from your own mods folder and are used only for sessions that announce the same hash. They never appear as installed mods and never run in single player.
- Downloaded mods are held to stricter limits (see file limits). Agreeing to the list is your consent to their permissions, for that server's sessions.
See Joining a modded server for what the player sees.
For server hosts
Mods marked "network": "required" or "optional" that you run are offered to every player who joins. Before hosting publicly, check a mod's permissions in Mods. Mods with building.limits or players.teleport change the game for everyone on your server.
Reporting a security problem
If you find a way for a mod to do something this page says it cannot, please report it to the Project Avion team privately rather than publishing it, so it can be fixed for everyone first.