Back to skill

Security audit

Production Docker Compose

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Docker Compose generator, but it has under-scoped secret handling and unsafe production defaults that users should review before installing.

Review and harden the generated Compose output before use. Prefer .env.example or source-derived variable names over reading live .env files, require explicit secrets instead of default passwords, avoid passing passwords in health-check command arguments, and confirm the deployment target is really production Docker Compose rather than development, Kubernetes, or a managed container platform.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (3)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:51
Finding

Unnecessary Access to Secret-Bearing Environment Files

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 51
Vulnerability Type: Excessive access to sensitive configuration
Risk Level: Medium

Vulnerable Code

markdown
6. **Environment variables** — scan `.env`, `.env.local`, `.env.example` for required vars

Technical Analysis

The skill instructs the agent to scan .env and .env.local, which commonly contain live database passwords, API keys, signing secrets, access tokens, and cloud credentials. Reading the values of these files is not necessary when the task only requires determining which environment variable names must appear in generated configuration.

This violates least-privilege principles by exposing sensitive values to the agent context when .env.example, application manifests, or key-only parsing would normally provide sufficient information. Once loaded, secret values may be included in conversation context, diagnostics, generated output, or platform logs. The audited instruction does not explicitly direct the agent to exfiltrate these values.

Attack Path

  1. A user invokes the skill on a project containing production credentials in .env or .env.local.
  2. The agent follows the instruction to scan those files.
  3. The complete secret values are loaded into the agent or tool context.
  4. Values may subsequently be exposed through generated content, debugging output, telemetry, logs, or accidental context disclosure.

Impact Assessment

Exposure is limited to secrets present in the environment files the executing user can already access. Depending on those credentials, compromise could extend to databases, third-party APIs, cloud resources, session-signing systems, or other production services. This instruction does not independently grant filesystem privileges or bypass operating-system access controls.

Remediation
View remediation

Remediation Suggestions

  • Inspect .env.example by default rather than live .env files.
  • Derive required variable names from manifests, source references, and existing Compose configuration.
  • Request explicit user authorization before reading .env or .env.local.
  • If access is authorized, extract only variable names and never return, log, or retain their values.
  • Apply automatic redaction to values associated with keys containing terms such as PASSWORD, SECRET, TOKEN, KEY, or CREDENTIAL.
  • Document that production environment files should remain outside agent context unless their contents are indispensable to the requested task.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:162
Finding

Predictable Default Redis Password in Generated Production Configuration

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 162-168
Vulnerability Type: Hardcoded fallback credential
Risk Level: High

Vulnerable Code

yaml
command: redis-server --requirepass ${REDIS_PASSWORD:-changeme} --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
  - redisdata:/data
networks:
  - database
healthcheck:
  test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-changeme}", "ping"]

Technical Analysis

The ${REDIS_PASSWORD:-changeme} expression silently substitutes the publicly predictable password changeme whenever REDIS_PASSWORD is unset or empty. This creates an operationally valid deployment with a known credential instead of failing securely.

The behavior contradicts the skill's stated goal of generating production-grade configuration and its prohibition against hardcoded credentials. Although Redis is assigned to an internal database network in the proposed topology, any compromised, malicious, or unintended container attached to that network can attempt authentication using the known fallback.

Attack Path

  1. An operator generates and starts the Compose configuration without setting REDIS_PASSWORD, or sets it to an empty value.
  2. Compose expands the fallback expression to changeme.
  3. Redis starts successfully and uses changeme as its authentication password.
  4. An attacker gains execution in an application container or another workload with access to the database network.
  5. The attacker connects to the Redis service and authenticates using the known password.
  6. The attacker can read, modify, inject, or delete data available through that Redis instance, subject to Redis configuration and command restrictions.

Impact Assessment

A successful attacker can obtain the privileges assigned to the authenticated Redis user. With the shown configuration and no Redis ACL restrictions, this may include access to cached application data, sessi ...[truncated 264 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace every Redis fallback with a required-variable expression:

    yaml
    command: redis-server --requirepass ${REDIS_PASSWORD:?REDIS_PASSWORD is required} --maxmemory 256mb --maxmemory-policy allkeys-lru
    
  • Prefer Docker Compose secrets or a protected Redis configuration file over passing the password directly in the command.

  • Generate a cryptographically random password during secure deployment provisioning rather than embedding any default.

  • Configure Redis ACLs with a dedicated least-privileged application user.

  • Preserve network isolation and ensure untrusted services cannot join the database network.

  • Add deployment validation that fails if the password is absent, empty, or equal to known placeholders such as changeme or CHANGE_ME_STRONG_PASSWORD.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:168
Finding

Database Credentials Exposed in Health-Check Process Arguments

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 168 and 241
Vulnerability Type: Plaintext credentials in command-line arguments
Risk Level: Medium

Vulnerable Code

yaml
healthcheck:
  test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-changeme}", "ping"]
yaml
healthcheck:
  test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]

Technical Analysis

Both health checks supply passwords as command-line arguments. Command arguments can be exposed through process inspection, container diagnostics, orchestration metadata, debugging tools, or logs that reproduce executed commands. The MySQL health check additionally uses the root database credential, increasing the value of any disclosure.

Exploitation requires sufficient local or container-level visibility to inspect the health-check process or associated metadata. Container isolation reduces exposure to unrelated host users, but administrators, monitoring agents, privileged containers, processes sharing a PID namespace, or attackers who already have execution in the relevant container may be able to observe the credentials.

Attack Path

  1. Docker periodically executes the Redis or MySQL health check.
  2. The database password is included in the resulting process argument list.
  3. An attacker with process-inspection, container-debugging, or equivalent diagnostic access observes the health-check invocation.
  4. The attacker extracts the Redis password or MySQL root password.
  5. The attacker connects to the corresponding database through an accessible network path and authenticates with the recovered credential.

Impact Assessment

Disclosure of the Redis credential grants the permissions associated with the configured Redis user, potentially exposing sessions, queues, and cached data. Disclosure of MYSQL_ROOT_PASSWORD is more severe because it may provide unrestricted administ ...[truncated 209 chars]

Remediation
View remediation

Remediation Suggestions

  • Do not place passwords in health-check command arguments.
  • Store credentials in Docker Compose secret files with restrictive permissions.
  • For MySQL, use a protected client configuration file referenced by mysqladmin, and create a dedicated least-privileged health-check account instead of using root.
  • For Redis, use a protected configuration or supported secret-injection mechanism that avoids exposing the password in the process argument list.
  • Restrict access to container process information, the Docker socket, container diagnostics, and monitoring systems.
  • Avoid shared PID namespaces unless explicitly required.
  • Ensure health-check output and command metadata are redacted from operational logs and dashboards.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (7)

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The skill instructs the agent to load .env directly via env_file for production services while simultaneously framing itself as production-grade. In Compose deployments, .env-based secret handling commonly results in secrets being stored unencrypted on disk, copied across environments, and accidentally committed or leaked through poor operational hygiene, especially because the skill normalizes this as the default path.

Content

Scanner excerpt · SKILL.md (reported line 81)May include surrounding context.

md
ports:
      - "127.0.0.1:${APP_PORT:-3000}:${APP_PORT:-3000}"
    env_file:
      - .env
    networks:
      - frontend
      - backend

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 326)May include surrounding context.

yaml
secrets:
  db_password:
    file: ./secrets/db_password.txt
  api_key:
    file: ./secrets/api_key.txt

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The same production secret-handling weakness is repeated for the worker service, propagating insecure .env-based secret usage across additional containers. Replicating this pattern increases the blast radius of a single file compromise and encourages broader reuse of shared credentials across services.

Content

Scanner excerpt · SKILL.md (reported line 421)May include surrounding context.

md
restart: unless-stopped
    command: <worker-command>  # e.g., "npm run worker", "celery -A app worker"
    env_file:
      - .env
    networks:
      - backend
      - database

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest description says the skill 'includes ... secrets management', implying it is part of the default generated production configuration. However, the body later says to default to env_file and only offer Compose secrets: when the user explicitly asks for tighter security, which contradicts the claim that secrets management is included as a standard part of output.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger phrases are very broad and likely to activate for generic containerization requests, causing this skill to take over contexts where a simpler, development, Kubernetes, or platform-specific workflow would be safer and more appropriate. Over-broad activation can lead to incorrect automation, unnecessary exposure of deployment assumptions, and insecure copy-paste adoption in mismatched environments.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The 'When to Use' section is ambiguous and lacks sharp boundaries, encouraging invocation whenever users mention Dockerizing an app or adding networking/resource limits. This increases the chance the agent applies production patterns in unsuitable environments, potentially producing configs that are insecure, misleading, or operationally broken for the user's actual deployment target.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill's network-segmentation instructions are internally inconsistent: one section says database services must be on the database network only, while another says the app service should connect to the database network even though the example app service block omits it. This can cause the agent to generate nonfunctional or incorrectly segmented Compose files, leading users to weaken isolation ad hoc or expose services improperly during troubleshooting.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.