170 lines
7.7 KiB
Markdown
Executable File
170 lines
7.7 KiB
Markdown
Executable File
# Security Policy
|
|
|
|
## Supported versions
|
|
|
|
drivestage is pre-1.0 software. Only the most recent minor release line
|
|
receives security fixes.
|
|
|
|
| Version | Supported | Notes |
|
|
|---------|--------------------|--------------------------------------|
|
|
| 0.2.x | :white_check_mark: | Current release line |
|
|
| 0.1.x | :x: | EOL — upgrade to 0.2.x |
|
|
| < 0.1 | :x: | Never released |
|
|
|
|
When 0.4.0 ships, 0.2.x will move to a 30-day security-only window before EOL.
|
|
|
|
---
|
|
|
|
## Reporting a vulnerability
|
|
|
|
**Do not open a public GitHub issue for security vulnerabilities.**
|
|
|
|
Email vulnerability reports to **[security@dcos.net](mailto:security@dcos.net)**.
|
|
Please include:
|
|
|
|
1. A description of the issue and its impact.
|
|
2. The exact `blkstage.sh` subcommand(s) or GUI flow involved.
|
|
3. Reproduction steps (commands, ISO filenames, device path).
|
|
4. The output of `blkstage.sh --version`.
|
|
5. Your distro, kernel, and (if relevant) Rust toolchain version.
|
|
6. Any suggested remediation.
|
|
|
|
You will receive an acknowledgement within **5 business days**. If you do not,
|
|
follow up — the maintainer may be offline.
|
|
|
|
### Coordinated disclosure
|
|
|
|
We follow a **90-day coordinated disclosure** timeline:
|
|
|
|
| Day | Action |
|
|
|------|-------------------------------------------------------------------|
|
|
| 0 | Reporter emails `security@dcos.net` |
|
|
| ≤ 5 | Maintainer acknowledges receipt |
|
|
| ≤ 14 | Maintainer triages and assigns a severity (see below) |
|
|
| ≤ 30 | Maintainer proposes a fix or mitigation; reporter reviews |
|
|
| ≤ 60 | Fix lands on a maintenance branch and a patch release is cut |
|
|
| ≤ 90 | Public advisory published (CVE requested if eligible) |
|
|
|
|
If a fix is delayed, the reporter is kept informed at each milestone. Reporters
|
|
who wish to extend the 90-day window are encouraged to ask — extensions are
|
|
granted in good faith.
|
|
|
|
### Severity
|
|
|
|
We use [CVSS v3.1](https://www.first.org/cvss/calculator/3.1). Examples
|
|
relevant to this project:
|
|
|
|
| Severity | Example |
|
|
|-----------|----------------------------------------------------------------------------------|
|
|
| Critical | Script wipes the OS disk on a non-USB device under any input |
|
|
| High | Sudo password leaks to disk, logs, or another process |
|
|
| Medium | A distro-detection false negative causes the wrong kernel args on a known ISO |
|
|
| Low | Cosmetic information leak (e.g. device serial printed to stdout) |
|
|
|
|
---
|
|
|
|
## Threat model
|
|
|
|
drivestage is a **disk-destroying, privilege-elevating** tool. Treat it
|
|
with the same caution as `dd`, `mkfs`, or `parted`. The realistic threats are:
|
|
|
|
1. **Wrong-device wipe.** The user runs `setup` against a path that turns out
|
|
to be the OS disk, an LVM member, or a LUKS-backed device. Data loss is
|
|
total and unrecoverable.
|
|
2. **Credential exposure.** The GUI captures the user's sudo password to run
|
|
the engine. A leak (logs, core dump, swap, /proc/<pid>/environ) discloses
|
|
it to other local users or to anyone with later physical access.
|
|
3. **Tampered config file.** `blkstage.sh` sources an optional
|
|
`CONF_FILE` (`/etc/drivestage.conf`). A world-writable or non-root-owned
|
|
conf file is a local privilege escalation vector — any user could plant
|
|
shell that runs as root on the next invocation.
|
|
4. **Concurrent invocation.** Two `setup` or `deploy` runs racing on the same
|
|
device produce a corrupted partition table or half-written GRUB image.
|
|
5. **Hostile ISO payloads.** The tool copies ISO files verbatim. It does not
|
|
inspect ISO contents. Booting a malicious ISO is the user's responsibility
|
|
— but the tool must not silently boot a different ISO than the one the user
|
|
selected.
|
|
6. **CI/supply-chain.** A compromised dependency in `Cargo.lock` could ship
|
|
malicious code into the GUI binary.
|
|
|
|
The tool is **not** designed to defend against an attacker with write access
|
|
to the drivestage installation itself (`/usr/local/bin/drivestage`,
|
|
`/usr/local/lib/drivestage/`, or the git checkout). At that point the
|
|
attacker already has the privileges the tool runs with.
|
|
|
|
---
|
|
|
|
## Security measures in place
|
|
|
|
The following mitigations are present in 0.2.x. Each is documented in
|
|
[`CHANGELOG.md`](./CHANGELOG.md) and tested where feasible.
|
|
|
|
### Disk safety
|
|
|
|
- **`guard_root_disk`** refuses to operate on the device hosting `/`. It walks
|
|
the `lsblk PKNAME` chain so it also catches the OS disk when root sits on
|
|
LVM, LUKS, or mdadm. A second check blocks any device whose `PKNAME` chain
|
|
mentions `crypt`, `lvm`, `md`, or `dm-`.
|
|
- **Typed confirmation.** `setup` requires the user to type the device name
|
|
verbatim before any destructive operation begins.
|
|
- **Recursive unmount.** `unmount_all` uses `umount -R` so nested mounts under
|
|
`/mnt/drivestage/*` are cleaned up before re-partitioning.
|
|
- **Free-space check.** `deploy_payload` verifies sufficient free space on the
|
|
payloads partition before invoking `rsync`.
|
|
- **Cleanup trap.** A trap on `EXIT`/`INT`/`TERM` calls `unmount_all` so a
|
|
Ctrl-C mid-deploy doesn't leave partitions mounted and confusingly writable.
|
|
|
|
### Credential handling
|
|
|
|
- **`Zeroizing<String>`** wraps the sudo password in the GUI (`core/sudo.rs`).
|
|
The string is zeroized on drop — never written to logs, never serialized,
|
|
never sent across an IPC channel that persists.
|
|
- **`flock`-based single-instance lock.** Concurrent invocations are refused
|
|
with an explicit error rather than racing on shared state.
|
|
- **No password on the command line.** The script never accepts a password as
|
|
an argument or environment variable; the GUI passes it through `sudo -S`'s
|
|
stdin only.
|
|
|
|
### Configuration file safety
|
|
|
|
- **`CONF_FILE` ownership and mode validation.** Before sourcing
|
|
`/etc/drivestage.conf`, the script verifies:
|
|
- Owner is `root:root`.
|
|
- Mode is `0644` or stricter (no group/other write).
|
|
- File is a regular file (not a symlink, FIFO, or device node).
|
|
Failure aborts before sourcing.
|
|
|
|
### Build & supply chain
|
|
|
|
- **Pinned `Cargo.lock`.** The lockfile is committed; CI runs `--locked` for
|
|
test/build/clippy. A `cargo update` is a deliberate, reviewable change.
|
|
- **Dependabot** opens PRs for cargo + GitHub Actions dependency updates on a
|
|
weekly cadence (see [`.github/dependabot.yml`](./.github/dependabot.yml)).
|
|
- **CI gate.** Every push and PR runs `fmt`, `clippy -D warnings`, `test`,
|
|
`build --release`, `shellcheck`, `bash-tests`, and MSRV check on Rust 1.75
|
|
and stable (see [`.github/workflows/ci.yml`](./.github/workflows/ci.yml)).
|
|
|
|
---
|
|
|
|
## Hardening recommendations for users
|
|
|
|
- Install the script to a root-owned, mode-0755 location
|
|
(`/usr/local/bin/drivestage`).
|
|
- If you use `/etc/drivestage.conf`, `chown root:root` it and `chmod 0644`
|
|
it. The script will refuse to source it otherwise.
|
|
- Run the GUI as your normal user, not as root. The GUI escalates via `sudo`
|
|
only when needed; running it as root skips the privilege boundary.
|
|
- Verify the device path with `lsblk` before each `setup`. The script's
|
|
`guard_root_disk` catches the OS disk — it does **not** catch a second data
|
|
disk you care about.
|
|
- Don't leave a drivestage stick plugged into a multi-user host. The
|
|
payloads partition is world-readable ext4 by default.
|
|
|
|
---
|
|
|
|
## Contact
|
|
|
|
- **Security reports:** [security@dcos.net](mailto:security@dcos.net)
|
|
- **General issues:** [GitHub Issues](https://git.dcos.net/dcosnet/DriveStage/issues)
|
|
- **Maintainer:** Jeremy Anderson <info@dcos.net> — [dcos.net](https://dcos.net)
|