# Security ## Reporting a vulnerability Please report security issues **privately** through [GitHub's private vulnerability reporting](https://github.com/islamdiaa/dropbox-docker/security/advisories/new) (Security tab → Report a vulnerability), not as a public issue. The aim is to respond within a week and release a fix or mitigation as soon as practical, with credit to you unless you prefer otherwise. If that form isn't available, contact the maintainer privately through [itayar.com](https://itayar.com) instead. Problems in the Dropbox client itself should go to [Dropbox's bug bounty program](https://hackerone.com/dropbox). ## Supported versions Only the latest release gets fixes. Use `latest` (or `stable`, which is the same image) or the newest `X.Y.Z` tag. | Tag | Supported | |---|---| | `latest`, `stable`, newest `X.Y` | Yes, including the monthly rebuild with Ubuntu's security updates | | Newest `X.Y.Z` | Yes, but it is never rebuilt: it stays exactly as released | | `development` | No: it carries unreleased changes | | Older version tags, dated tags (e.g. `20261001`), commit tags | No | ## What this project controls This container downloads and runs the official Dropbox daemon from `dropbox.com`, unmodified. The security of the Dropbox client and sync protocol is Dropbox's responsibility. What we control: - The base image (Ubuntu 24.04 LTS) and its packages - The entrypoint (settings, permissions, process supervision, signal handling) - The healthcheck - The monitoring service: status page, JSON API and Prometheus metrics - The CI pipeline that builds, tests, scans and publishes the image ## Trust model ### Downloads from Dropbox Two files come from Dropbox over HTTPS: 1. **The Dropbox daemon**, downloaded at startup from `https://www.dropbox.com/download?plat=lnx.x86_64` when a newer version is available 2. **The Dropbox CLI script**, included in the image at build time from `https://www.dropbox.com/download?dl=packages/dropbox.py` Dropbox doesn't publish checksums or signatures for its Linux client, so integrity can't be verified beyond TLS. If `dropbox.com` or its CDN were compromised, a malicious client could be installed. Mitigations: - Downloads use HTTPS with certificate verification and time out instead of hanging. - The daemon runs as an unprivileged user (via `gosu`), limiting what a compromised client could do. - `DROPBOX_SKIP_UPDATE` keeps the installed client instead of downloading a new one. ### Container privileges - The entrypoint runs as root, which it needs to map UID/GID and fix permissions. The Dropbox daemon and the monitoring service run as the unprivileged `dropbox` user. - No `--privileged`, no `docker.sock`, no host networking. - The container works with `cap_drop: ALL` plus `CHOWN`, `SETUID`, `SETGID`, `FOWNER` and `DAC_OVERRIDE` (see `docker-compose.yml`). It doesn't need `KILL`. - The ownership repair pass changes symlinks themselves (`chown -h`), never their targets, and changes each file from inside its own folder (`find -execdir`), so a folder swapped for a symlink mid-walk can't redirect it. - Root never deletes, chowns or chmods through paths inside folders the Dropbox user owns: cleanup there runs as the Dropbox user, and root only creates folders with `mkdir`, which never follows a symlink. - The Dropbox download is unpacked without its archived owners or setuid bits. ### Input validation Every setting is validated before use: - `TZ` is checked against a character allowlist before it's used in a file path. - `DROPBOX_UID`, `DROPBOX_GID` and all interval, timeout and count settings must be numbers. - `OWNERSHIP_FIX_MODE` must be one of the documented values. - Nothing from the environment is passed to `eval` or a shell. ### Monitoring endpoints With `ENABLE_MONITORING=true`, two HTTP servers listen on all interfaces inside the container: - Port 8001: status page, `/status` and `/health` - Port 8000: Prometheus `/metrics` They're **unauthenticated** and meant for a trusted LAN. They don't expose your email or name, but they do show file and folder names: excluded folders, the file currently syncing, and the file named in the last sync error. The status page sends a strict Content-Security-Policy, `X-Content-Type-Options: nosniff` and `Referrer-Policy: no-referrer`, loads nothing from other sites, and never shows the account link URL. Don't publish these ports to the internet; use a reverse proxy with authentication if you need remote access. ### Supply chain and CI - Every image is built, tested end to end and scanned with Trivy (CRITICAL/HIGH with a fix available fail the build) **before** it's published, and the image that is published is that same tested image, not a rebuild. Pull requests run the same checks. - CodeQL analyzes the Python code and the workflows; OpenSSF Scorecard checks the repository. - All GitHub Actions are pinned to commit SHAs, workflows have read-only permissions by default, and checkouts don't keep credentials. - Dependabot updates actions and Python packages weekly; the monthly build pulls the latest Ubuntu 24.04 base image and is published as `development`, a dated tag and, when nothing in the image has changed since the last release, as `latest`, `stable` and that release's `X.Y` tag. - Registry credentials are GitHub Actions secrets and are never used by pull request builds.