Security

The REST API gives full control over the emulated machine -- memory access, input injection, shutdown. That makes the webserver an attack surface by design. Here is what dosbox-automation does to keep it safe, and what you should be aware of.

Authentication

Every API request must include a bearer token in the Authorization header:

Authorization: Bearer <token>

The token is a random 64-character hex string generated fresh each time dosbox-automation starts. The full token is never printed to the log. It can be provided via the DOSBOX_API_TOKEN environment variable, written to a file with webserver_token_file, or (as fallback) the first 8 characters are shown in the log. See the Webserver page for details. There is no default password and no way to disable authentication.

Token comparison uses constant-time string matching to prevent timing attacks.

Network binding

The webserver binds to 127.0.0.1 (localhost) by default. Only processes on the same machine can reach it. This is controlled by the webserver_bind_address setting.

Warning

Do not bind to 0.0.0.0 or an external IP address unless you fully understand the implications. The API provides unrestricted access to emulator internals, including memory read/write. Exposing it to a network means anyone who obtains the token -- or exploits a vulnerability -- has full control.

Host header validation

The webserver checks the Host header on every incoming request against a whitelist derived from the bind address. Requests with an unexpected host header are rejected with HTTP 403.

This prevents DNS rebinding attacks, where a malicious website tricks your browser into making requests to localhost on your behalf.

CORS policy

No CORS headers are set. The server does not include Access-Control-Allow-Origin or any other CORS response header, so browsers block cross-origin requests by default. The built-in API tools served from the config directory work because they are loaded as local files, not from a remote origin.

OPTIONS requests (CORS preflight) are rejected with HTTP 403. The only non-standard header set by default is X-Content-Type-Options: nosniff.

Payload limits

Request bodies are capped at 10 MiB. This prevents a malicious client from exhausting memory by sending oversized payloads.

Mount path validation

Every path used in a MOUNT, BOOT, or drive-swap operation is validated before the drive is constructed. The checks run regardless of whether the webserver is enabled.

Floor checks (always active):

  • Path must resolve via the filesystem (no dangling references)
  • No symlink components anywhere in the path
  • System directories are blocked (/etc, /proc, /usr, /dev, /boot, /sys, /run, /var, /sbin, /lib, /bin, /lib32, /lib64, /libx32, /root, /snap, and bare root on Linux; Windows equivalents on Windows)
  • Disk images must pass structural validation: ISO 9660 magic bytes, FAT boot signature, known floppy sizes, or valid CUE sheet syntax. A file that does not look like a real disk image is rejected.

Whitelist enforcement (webserver on or autoexec-driven mount):

When the webserver is enabled, directory mounts are restricted to the config file's parent directory and any additional paths configured via mount_allowed_bases. This prevents an injected MOUNT command from reaching arbitrary host directories.

The drive-swap API endpoint additionally checks mount_allowed_image_roots and mounts images read-only by default.

Mount lock:

The API exposes a one-way lock at POST /api/v1/mount/lock. Once engaged, all mount operations are refused: directory mounts, image mounts, and BOOT. The lock check runs before path validation, so a locked emulator rejects mount requests immediately regardless of whether the path would otherwise be allowed. The lock cannot be reversed without restarting the emulator.

Launchers should call mount lock after installation completes. For multi-disc games, all disc swaps must happen before locking.

Config isolation:

mount_allowed_bases and mount_allowed_image_roots are read from the primary config file only. A bundled game config passed via --conf cannot widen the whitelist, even though it can set other [webserver] options. This prevents a malicious game config from adding /etc to the allowed list and then mounting it via its own [autoexec].

Why the mount policy exists

Standard DOSBox lets MOUNT and IMGMOUNT reach any directory or file on the host. That is fine when you are the only person typing commands at the DOS prompt. It is not fine when a REST API accepts mount paths from external tools, or when an autoexec section in a bundled game config runs mount commands at startup. Without restrictions, a crafted config file or API request could mount /etc, /home, or the root filesystem into the emulated DOS environment and read or write host files.

dosbox-automation locks this down in layers: block dangerous paths outright, restrict what is left to a configurable whitelist, and provide a one-way lock that freezes the drive layout once installation is done. The floor checks run even without the webserver, so a malicious .conf file cannot reach system directories through its autoexec section either.

Mount policy at a glance

This table shows what happens when you try to mount different kinds of paths. "Webserver off" means the REST API is disabled and no whitelist is configured. "Webserver on" means the webserver is running and whitelist settings apply.

Mount operationWebserver offWebserver on, no whitelistWebserver on, whitelisted
MOUNT C /home/user/gamesAllowedAllowed (config dir parent)Allowed if under a listed path
MOUNT C /home/user/games (from autoexec in --conf)AllowedValidated against whitelistValidated against whitelist
MOUNT C /etcBlocked (system dir)Blocked (system dir)Blocked (system dir)
MOUNT C /Blocked (root)Blocked (root)Blocked (root)
MOUNT C /home/user/link-to-etc (symlink)Blocked (symlink)Blocked (symlink)Blocked (symlink)
MOUNT A disk.img -t floppy (valid image)AllowedAllowedAllowed
MOUNT A notes.txt -t floppy (not an image)Blocked (validation)Blocked (validation)Blocked (validation)
Drive swap via APIN/A (no API)Allowed if mount_allowed_image_roots not setAllowed if image under listed root
Drive swap after mount lockN/ABlocked (locked)Blocked (locked)
--conf game.conf widens whitelistN/AIgnored (primary only)Ignored (primary only)

The "Allowed (config dir parent)" case means that with the webserver on but no explicit mount_allowed_bases, directory mounts default to the parent directory of the primary config file. Set mount_allowed_bases to restrict or widen this to your game library paths.

Common problems and how to fix them

"Path is not under any allowed base directory"

Your mount_allowed_bases does not include the directory you are trying to mount. Add the game library path to the primary config file:

[webserver]
mount_allowed_bases = $HOME/Games;$HOME/dos

Environment variables $HOME, %USERPROFILE%, and $XDG_DATA_HOME are expanded. Maximum 5 entries, separated by semicolons.

"Symlink in path" on a mount that looks normal

One of the directories in the path is a symlink. dosbox-automation rejects symlinks at every component, not just the final target. Check with readlink -f /your/path to see the resolved path, then mount the real path instead.

"Invalid disk image" on a file that works in other DOSBox versions

dosbox-automation validates that image files look like actual disk images before mounting them. The file must have ISO 9660 magic bytes, a valid FAT boot sector signature, match a known floppy size (160K, 180K, 320K, 360K, 720K, 1.2M, 1.44M, 2.88M), or be a syntactically valid CUE sheet. The early sizes matter for self-booting games: pre-DOS-2.0 disks carry no FAT boot signature, so the size check is what lets them through. Renamed ZIP files, text files, or truncated downloads will be rejected. If you have a legitimate image that fails validation, check that the file is complete and not corrupted.

Drive swap fails with "Mount lock is engaged"

The mount lock was called before all disk swaps were done. For multi-disk installs, do all swaps first, then lock. The lock is one-way and cannot be reversed without restarting dosbox-automation.

"BOOT command is blocked"

The BOOT command is covered by the mount lock. If you need BOOT for a booter game, do not engage the mount lock before booting. BOOT is also blocked if the image path fails the same validation as regular image mounts.

Autoexec mount fails, but the same command works at the DOS prompt

When the webserver is enabled, autoexec-driven mounts go through the same whitelist enforcement as API-driven mounts. A MOUNT in a --conf file must point to a path allowed by the primary config's mount_allowed_bases. Move the path into the primary config's whitelist, or use the primary config's autoexec section instead of a secondary --conf file.

What the API does not protect against

  • A program running on the same machine as dosbox-automation can read the token from the log output or from process memory. Localhost binding is not a security boundary against local processes -- it is a boundary against remote access.

  • The API does not rate-limit requests. A local process with the token can make as many requests as it wants.

  • File paths served from the config directory (webserver folder) are not sandboxed beyond the mount point. Do not put sensitive files in that directory.

Reporting security issues

If you find a security vulnerability in dosbox-automation, please report it through GitHub Issues or contact us directly via the contact page. We take security reports seriously and will respond promptly.

Configuration settings

See the Webserver page for all webserver configuration options.