T05 · Unauthorized Access and Privilege Escalation
Warning
- Location
- references/replication.md:220
- Finding
- Passwordless SSH Replication Credential Grants Broad Destructive Access<![CDATA[ ## Vulnerability Details **File Location**: `references/replication.md`, lines 220-232 **Vulnerability Type**: Excessive delegated permissions and insufficiently restricted passwordless SSH authentication **Risk Level**: Medium ### Vulnerable Code ```bash # On each replica host useradd -m -s /bin/bash zfsrepl # Grant only necessary ZFS permissions zfs allow -u zfsrepl create,mount,receive,destroy,rollback,hold,release backup ``` ```bash # On primary ssh-keygen -t ed25519 -f /root/.ssh/zfsrepl_key -N "" ssh-copy-id -i /root/.ssh/zfsrepl_key zfsrepl@replica1 ssh-copy-id -i /root/.ssh/zfsrepl_key zfsrepl@replica2 ``` ### Technical Analysis The guide creates a replication account with an interactive shell and delegates destructive ZFS permissions, including `destroy` and `rollback`. It then installs an SSH key with no passphrase through `ssh-copy-id`, which ordinarily adds an unrestricted entry to the remote account's `authorized_keys`. These capabilities are related to the declared replication functionality, so the behavior is not inherently malicious. However, the configuration does not enforce least privilege at the SSH boundary: - The account receives `/bin/bash` rather than a non-interactive or purpose-restricted command environment. - The SSH key is not restricted using an `authorized_keys` forced command. - No `from=` source-address restriction is applied. - Port forwarding, agent forwarding, X11 forwarding, PTY allocation, and arbitrary SSH commands are not explicitly disabled. - The delegated `destroy` and `rollback` permissions allow deletion of snapshots and reversal of destination data. - One private key is authorized on multiple replicas, increasing the blast radius of credential disclosure. The later replication example uses `zfs recv -F`, which can roll back or remove destination-side state: ```bash zfs send -Rw "$SNAP" | ssh -i "$SSH_KEY" "$host" "zfs recv -F $dataset" ``` Although `receive` is necessary for replication, destru ...[truncated 2039 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Create a non-interactive replication account where practical: ```bash useradd -m -s /usr/sbin/nologin zfsrepl ``` 2. Use a narrowly scoped forced-command wrapper that validates the permitted ZFS operation and destination dataset. Do not interpolate unvalidated dataset names into a shell command. 3. Restrict the public key in `authorized_keys`, for example: ```text from="192.0.2.10",restrict,command="/usr/local/sbin/zfs-receive-wrapper backup/data" ssh-ed25519 AAAA... ``` On systems without the `restrict` option, explicitly apply: ```text no-agent-forwarding,no-port-forwarding,no-X11-forwarding,no-pty ``` 4. Grant only the ZFS permissions needed by the selected workflow. Omit `destroy`, `rollback`, and `mount` unless forced receive or destination-side retention demonstrably requires them. 5. Prefer separate keys for each replica. This prevents disclosure of one key from compromising every backup target. 6. Protect private keys with strict ownership and mode: ```bash chown root:root /root/.ssh/zfsrepl_key chmod 600 /root/.ssh/zfsrepl_key ``` 7. Where unattended operation permits it, use an SSH agent, hardware-backed key, or tightly controlled secrets service instead of a permanently unencrypted private key. 8. Enable destination-side immutable retention, ZFS holds, snapshots inaccessible to the replication identity, or offline backup copies so compromise of the replication credential cannot erase every recovery point. 9. Document that `zfs recv -F` is destructive and require explicit confirmation or a verified common-snapshot check before enabling it. ]]>
