-
Notifications
You must be signed in to change notification settings - Fork 0
Plugin Trust Model
GamesDownloader plugins are not sandboxed scripts or a limited macro language. A plugin is ordinary Python code that GamesDownloader imports and runs inside its own process. This page explains, plainly, what that means for security, why the design is deliberate rather than a flaw, and how to stay safe.
The short version: installing a plugin is equivalent to running arbitrary software on your server. Treat it exactly as you would treat any other program you choose to run.
- What a plugin actually is
- This is by design, not a vulnerability
- Why this is acceptable in practice
- The guardrails that do exist
- What the guardrails are not
- Guidance for administrators
When GamesDownloader loads a plugin, it locates the plugin's entry file and executes it as a module (using Python's importlib machinery to build a spec from the file location and then run the module). That code runs in the same process as the application, so it inherits everything the application can do:
| A loaded plugin can reach | Because |
|---|---|
| The database | plugins are given a synchronous helper that connects using the app's own database URL, and nothing stops a plugin opening its own connection |
| The filesystem | it runs as the same OS user as the server, so it sees every file the container/process can read or write, including game files, ROMs, downloads, and config |
| Environment variables | it shares the process environment, which includes secrets such as database credentials and the auth signing key |
| The network | it can make outbound requests to anywhere the server can reach, including other machines on your LAN |
| Application internals | it can import backend modules, call handlers, and register hooks that run on real requests |
A plugin's declared Python dependencies (a requirements.txt inside the ZIP) are also installed and imported into the process, so any code in those dependencies runs with the same reach.
In one sentence: a plugin has the same privileges as GamesDownloader itself. There is no privilege boundary between the two.
This is the intended extension model, and it is the same trade-off every extensible application makes:
- A browser extension can read the pages you visit and your cookies.
- An IDE or editor plugin runs code with your user account on your machine.
- A CMS plugin (WordPress, etc.) runs PHP inside the site with database access.
None of these are considered bugs. They are the price of a rich extension system: to be genuinely useful, an extension has to be able to do things, and drawing a perfect sandbox around arbitrary third-party code while still letting it add metadata providers, download sources, themes, and widgets is not realistically achievable. GamesDownloader makes the same choice on purpose. The value of the plugin and theme ecosystem (see Plugin Development) depends on plugins being able to reach the database, the library, and the network.
So "a plugin can run any code" is a documented property of the system, not a hole to be reported.
The reason this is safe in normal operation is that installing a plugin is an administrator-only action, and an administrator is already the trust root of the instance.
Plugin installation and management endpoints are gated by a plugins.write permission scope, which is granted only to the admin role. Ordinary users, editors, and uploaders cannot install, enable, configure, or remove plugins.
An admin can already:
- read and change every setting,
- reach the database and the underlying host,
- add or remove users and grant admin rights.
An admin who installs a malicious plugin has therefore not crossed any new boundary - they already had full control. Conversely, a plugin only becomes a threat if the admin account itself is compromised, and at that point an attacker controls the whole instance regardless of plugins. There is no scenario where a non-admin gains extra power through the plugin system, because they cannot install plugins in the first place.
The real security boundary is admin login, not the plugin loader. Everything on this page reduces to: protect the admin account. See Security.
The plugin system is not a free-for-all. Several controls narrow the ways a plugin can arrive and how much can go wrong by accident, even though none of them sandbox the code once it runs:
| Control | What it does |
|---|---|
| Admin-only installation | install/enable/disable/remove all require the admin-only plugins.write scope |
| Admin login protection | admin authentication sits behind Redis brute-force rate limiting and optional two-factor authentication, so the boundary that matters is hardened |
| ZIP-only installation | plugins are installed by uploading a ZIP (or fetching one from a store source); there is no arbitrary "point it at a package name" path |
| No setuptools entry points | automatic discovery of installed pip packages as plugins is deliberately disabled, to avoid a supply-chain path where an unrelated package silently registers itself as a plugin |
| Zip Slip protection | archive extraction rejects absolute paths and .. components, and normalises separators, so a plugin cannot write files outside its own directory during install |
Path-traversal guard on entry (startup scan) |
during the startup directory scan the manifest's entry field is rejected if it contains .., /, or \, and the resolved path must stay inside the plugin directory. This check runs only on the startup scan, not on the runtime install/enable path (which relies on the Zip Slip protection above and the plugin-id check below instead) |
| Plugin id validation | the plugin id may not contain path separators or .., keeping each plugin confined to its own folder |
min_gd_version gate |
a plugin declaring a newer minimum GamesDownloader version than the running server is refused, so plugins run only against a version they were built for |
| Store install allowlist | one-click store installs will only download from github.com (and related GitHub hosts) or a store source you have explicitly configured, not from an arbitrary attacker-supplied URL |
To set expectations correctly:
- They do not sandbox plugin code. Once a plugin loads, it runs with full application privileges as described above.
- The path-traversal and Zip Slip checks protect where files land and which file is executed. They do not restrict what the executed code then does.
- The
min_gd_versiongate is a compatibility check, not a safety review. It says nothing about whether the plugin is trustworthy. - The store allowlist limits where a package is fetched from, not what is inside it. A malicious ZIP hosted on an allowlisted source is still malicious.
In other words, the guardrails reduce accidental damage and shrink the attack surface for reaching the loader. The decision about whether the code is trustworthy is yours.
Because installing a plugin runs its author's code on your server, apply the same judgement you would for any software you install:
- Only install plugins from sources you trust. Prefer the official template and store repositories and authors you recognise. An unknown ZIP from an unknown source is unknown code.
- Read what you can. Plugins are plain Python and assets; if you can review the source before installing, do.
- Keep the admin account locked down. Use a strong, unique password, enable two-factor authentication, and do not share admin credentials. This is the boundary that actually protects you.
- Prefer LAN-only or trusted-network exposure for admin access where possible, and review the hardening advice on the Security and Network and Security pages.
- Remove plugins you no longer use. Fewer installed plugins means less third-party code running in your process.
Rule of thumb: if you would not run a random program from this author on your server as a privileged user, do not install their plugin either. It is the same decision.
Next: Plugin Development - Security
Getting Started
Configuration
Features
- Dashboard
- Library
- Collections
- Game Requests
- GOG Integration
- ROMs & Emulation
- Downloads & Torrents
- Users & Permissions
- Themes
Plugin Development
Reference