Skip to content

Security: techdev-lab/restorelab

Security

SECURITY.md

Security Policy

Supported versions

Version 0.1.x is supported.

Reporting a vulnerability

Open a private security advisory on GitHub or email the maintainer. Include a minimal contract and reproduction steps. Do not open public issues for security bugs.

Threat model

What RestoreLab protects against

  • Corrupted PostgreSQL archives
  • Wrong Restic passwords
  • Missing snapshot paths
  • Oversized archives
  • Long or hanging restores
  • Accidental port publishing
  • Docker socket exposure
  • Production secret leakage
  • Resource exhaustion
  • Orphaned containers, volumes, networks

What RestoreLab does NOT protect against

  • Host compromise
  • Docker daemon compromise
  • Kernel vulnerabilities
  • Misconfigured Docker on the host
  • Files never in the backup
  • Full application startup
  • Cross-version PostgreSQL compatibility
  • Every form of arbitrary code execution

RestoreLab's trust boundary: the Restic archive contents are the only untrusted input. The contract file path, CLI arguments, and report output paths (JSON/HTML) are supplied directly by the operator invoking RestoreLab and are treated as trusted local input, not remote attacker input. gosec flags this pattern (G304, "potential file inclusion via variable") on ParseFile, WriteJSONFile, and WriteHTMLFile -- this is expected given the documented trust boundary above, not an oversight.

Known CVEs

CVE-2024-29018: DNS exfiltration from internal networks

Certain Docker Engine versions could forward DNS requests from containers attached only to an internal network to an external resolver, creating a possible DNS exfiltration path.

Fixed in: Moby 23.0.11, 25.0.4, 26.0.0.

RestoreLab requires Docker Engine 26.0.0 or later, unless the operator is running a supported patched maintenance branch.

RestoreLab does not claim absolute network isolation. It documents this as a Docker Engine limitation, not a RestoreLab bug.

CVE-2025-8714: pg_dump/pg_restore untrusted dump execution

A malicious PostgreSQL superuser can inject code into a dump file produced by pg_dump, pg_dumpall, or pg_restore. The injected content can execute on the client machine during restoration via psql, and pg_restore is affected when used to generate a plain-format dump.

Official guidance: never restore a dump from a server or user you do not explicitly trust.

RestoreLab mitigates this class of risk by:

  • Treating every archive as untrusted input
  • Restoring only inside a disposable sandbox
  • Never connecting to a production database
  • Never mounting the Docker socket
  • Blocking external network access where supported
  • Applying strict resource limits
  • Cleaning up unconditionally

This is a partial mitigation, not a guarantee. Operators must verify PostgreSQL patch status against CVE-2025-8714 on the server that produced the dump.

GO-2026-4887 / GO-2026-4883: Docker/Moby plugin vulnerabilities (no upstream fix)

govulncheck flags two vulnerabilities in github.com/docker/docker (the Docker Engine API client RestoreLab depends on, currently v28.5.2+incompatible):

  • GO-2026-4887: AuthZ plugin bypass via oversized request bodies.
  • GO-2026-4883: off-by-one error in plugin privilege validation.

Both report "Fixed in: N/A" as of 2026-09-14 -- no patched version of Moby has been released yet for either.

Assessment: RestoreLab never configures, installs, or invokes any Docker authorization (AuthZ) plugin or any other Docker plugin. It only calls the standard container/network/volume/image endpoints of the Docker Engine API (see "Isolation guarantees" below). The vulnerable code paths ship as part of the imported client library's surface but are not exercised by anything RestoreLab does. Tracked as an accepted risk, not exploitable via RestoreLab's own usage.

Action: re-run govulncheck ./... after every github.com/docker/docker version bump, and upgrade to a patched release as soon as one exists upstream.

Secret handling

RestoreLab does not embed secrets in contracts. The contract references environment variables by name:

  • RESTIC_REPOSITORY
  • RESTIC_PASSWORD_FILE
  • TEST_DB_PASSWORD

Rules:

  • Never use production passwords for TEST_DB_PASSWORD.
  • Restrict RESTIC_PASSWORD_FILE to mode 0600.
  • Never commit any secret file to version control.
  • RestoreLab redacts the password file path in log output.

Isolation guarantees

Setting values used by RestoreLab:

  • cap_drop: ALL
  • cap_add: CHOWN, DAC_OVERRIDE, FOWNER, SETGID, SETUID
  • security_opt: no-new-privileges:true
  • read_only: true
  • tmpfs: /tmp (256 MiB), /run/postgresql (64 MiB)
  • Published ports: none
  • Network: one internal bridge, Internal: true
  • Docker socket: never mounted
  • privileged: false
  • Memory: configurable, validated
  • PIDs: configurable, validated
  • Shared memory: configurable, must be <= memory

The artifact is bind-mounted read-only at /restorelab/artifact/BASENAME.

Version pinning

RestoreLab requires test.image to be pinned by digest (postgres:16@sha256:...). Floating tags are rejected at validation time.

There aren't any published security advisories