Back to skill

Security audit

Docker Volume Backup Or Restore

Security checks for vulnerabilities and agentic risk

Overview

This Docker backup skill is coherent, but it needs Review because it can affect all Docker volumes and containers, upload encrypted backups to a registry, expose the backup password through process/container metadata, and overwrite persistent volume data.

Install only if you are comfortable giving the skill Docker-level authority over local volumes and containers. Use a private registry, prefer digest-pinned restore images, run --dry-run first, verify the destination image name, avoid real passwords in shell history or CI logs, and assume restore can replace existing volume contents.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/docker_volume_backup_or_restore.sh:77
Finding

Encryption Password Exposed Through Process Arguments and Docker Container Metadata

Content
View full analysis
&2; exit 1; } ENCRYPT_PASSWORD="$1"; shift ;; ``` ```bash require_value "--encrypt-password" "$ENCRYPT_PASSWORD" export ENCRYPT_PASSWORD ``` ```bash docker run --rm --name "$BACKUP_CONTAINER_NAME" \ -v "$BACKUP_ARTIFACT_DIR:/artifact" \ -e ENCRYPT_PASSWORD="$ENCRYPT_PASSWORD" \ "${MOUNTS[@]}" "$HELPER_IMAGE" sh -lc ' ``` The documented invocation also encourages placing the password directly on the command line: ```bash bash docker_volume_backup_or_restore.sh \ --backup \ --encrypt-password 'your-password' ``` ### Technical Analysis The encryption password is accepted as a command-line argument. Depending on the operating system's process visibility policy, the argument may be visible in process listings or process metadata while the script is running. A command entered interactively may also remain in shell history, terminal logging, automation logs, or job-runner metadata. The script subsequently exports the password into its process environment and supplies its literal value to `docker run` using `-e ENCRYPT_PASSWORD="$ENCRYPT_PASSWORD"`. Docker records supplied environment variables in the temporary container's configuration. A user with access to the Docker daemon can inspect the container while it exists and recover the value. Although Docker access is already highly privileged on typical systems, storing a backup decryption credential in container metadata unnecessarily expands the number of interfaces through which it can be disclosed. Exporting the variable also makes it available to subsequently launched child processes. ### Attack Path 1. A ...[truncated 1339 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/docker_volume_backup_or_restore.sh:125
Finding

Unpinned Packages Installed at Runtime in a Sensitive Backup Container

Content
View full analysis
/dev/null mkdir -p /artifact/volumes for vol_path in /docker_volume/*; do [ -d "$vol_path" ] || continue vol_name=$(basename "$vol_path") tar czf - -C "$vol_path" . | openssl enc -aes-256-cbc -pbkdf2 -salt -pass env:ENCRYPT_PASSWORD -out "/artifact/volumes/${vol_name}.tar.gz.enc" done ' ``` ### Technical Analysis The Alpine helper image is pinned by digest, but the script runs: ```bash apk add --no-cache openssl tar ``` during every backup. The requested packages and their transitive dependencies are not pinned to exact versions or fixed artifacts. Consequently, the effective backup environment can change over time even though the base image digest remains fixed. Package installation executes downloaded package content inside a container that has: - The encryption password in its environment. - Read access to all selected Docker volumes. - Write access to the host-backed backup artifact directory. - Network access under Docker's default networking configuration. Alpine package repositories normally provide integrity and signing controls, but runtime installation still introduces a mutable supply-chain dependency. A compromised repository, signing infrastructure, mirror, or accepted malicious package update could execute code in this sensitive context. Ordinary package changes could also introduce incompatible behavior and make backups ...[truncated 1687 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/docker_volume_backup_or_restore.sh (reported line 33)May include surrounding context.

sh
[[ "$DRY_RUN" -eq 1 ]] && exit "$exit_code"
  [[ -n "${BACKUP_CONTAINER_NAME:-}" ]] && docker rm -f "$BACKUP_CONTAINER_NAME" >/dev/null 2>&1 || true
  [[ -n "${RESTORE_CONTAINER_NAME:-}" ]] && docker rm -f "$RESTORE_CONTAINER_NAME" >/dev/null 2>&1 || true
  [[ -n "${WORKDIR:-}" && -d "$WORKDIR" ]] && rm -rf "$WORKDIR" || true
  if [[ "${MODE:-}" == "backup" && -n "${STOP_CONTAINERS[*]:-}" ]]; then
    log "Restarting containers that were stopped for backup..."
    docker start "${STOP_CONTAINERS[@]}" >/dev/null || true

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Restore writes decrypted archive contents directly into Docker volumes, potentially overwriting existing application data with no explicit confirmation or safety interlock. In this skill's context, that is particularly dangerous because the tool targets persistent state, so a mistaken image reference or operator error can cause destructive data loss across services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The backup workflow explicitly pushes encrypted volume archives to a Docker registry, but the backup mode description does not prominently warn that potentially sensitive data leaves the local host and is transmitted to external infrastructure. Even with encryption, this can create confidentiality, compliance, and operational risk if users mistakenly assume the process is purely local or use an unintended registry/account.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The usage text says the encryption password is never read from an environment variable, but the script exports it and passes it to Docker and OpenSSL via environment variables. In practice this can expose the secret to child processes, debugging tools, container inspection surfaces, or operator misunderstanding, making the documentation mismatch itself security-relevant.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

In backup mode, the script stops running containers, builds a backup image, and pushes it to a registry. Although logging and usage text mention these actions, there is no interactive confirmation before performing operations that can disrupt services and transmit backup data off-host.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding

The restore path pulls a user-supplied image reference that is only checked for non-empty and no whitespace, so mutable tags are allowed. In this skill's context, the backup image is treated as the source of truth for restoration, so pulling an unpinned tag can restore attacker-controlled or unexpectedly changed data from a registry.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest promises 'safe restoration without executing untrusted code,' and the log message says it copies archives out 'without running its command path'. However, the restore flow still performs docker pull and docker create on the supplied image, which is materially more interaction with an untrusted image than the wording suggests, even if it does not start the container process.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

The script creates a container from a user-supplied restore image that may be tag-based and registry-controlled by an attacker. Although it does not intentionally run the image's command path, using an unpinned image still trusts mutable remote content and can import malicious backup payloads or unexpected filesystem contents into the restore workflow.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script writes container and volume inventories to local plaintext files outside the encrypted backup artifact flow. In this context, those lists can disclose operational metadata such as container names and mounted volume names, which may be sensitive in shared workstations or CI runners even if the volume contents remain encrypted.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

Low
Category
Tool Misuse
Confidence
15% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/docker_volume_backup_or_restore.sh (reported line 184)May include surrounding context.

sh
RESTORE_STAGING="$WORKDIR/restore-staging/$volume"
    mkdir -p "$RESTORE_STAGING"
    openssl enc -d -aes-256-cbc -pbkdf2 -pass env:ENCRYPT_PASSWORD -in "$WORKDIR/volumes/${volume}.tar.gz.enc" | tar xzf - -C "$RESTORE_STAGING"
    docker run --rm -v "$volume:/target" -v "$RESTORE_STAGING:/source:ro" "$HELPER_IMAGE" sh -lc 'cp -a /source/. /target/'
  done
  log "Restore complete. Restored volumes listed in ./volume_list"
fi

Static analysis

No suspicious patterns detected.