Back to skill

Security audit

Postgres Manager

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local PostgreSQL manager, but it starts a persistent shared Docker database with documented default credentials, so users should review its configuration before use.

Use this only for local development data unless you first set a strong POSTGRES_PASSWORD, consider a dedicated Docker network instead of the shared default, and rotate credentials for any existing volume. Be aware that data persists in a Docker volume and that psql gives direct database access.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
docker-compose.yml:6
Finding

Predictable Default PostgreSQL Credentials on a Shared Docker Network

Content
View full analysis

Vulnerability Details

File Location: docker-compose.yml:6-8
Vulnerability Type: Hard-coded predictable default credentials
Risk Level: High

yaml
environment:
  POSTGRES_USER: ${POSTGRES_USER:-codai}
  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-pgpass}
  POSTGRES_DB: ${POSTGRES_MAIN_DB:-codai_main}

Related fallback in run.sh:30-35:

bash
POSTGRES_USER="${POSTGRES_USER:-codai}"
POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-pgpass}"
POSTGRES_MAIN_DB="${POSTGRES_MAIN_DB:-codai_main}"
if [ "$POSTGRES_PASSWORD" = "pgpass" ] && [ "${ACTION:-}" != "status" ] && [ "${ACTION:-}" != "wait" ] && [ "${ACTION:-}" != "psql" ]; then
    echo "Aviso: usando senha PostgreSQL padrão. Defina POSTGRES_PASSWORD para ambientes com dados reais."
fi

The working default credentials are also disclosed in SKILL.md:84-88 and SKILL.md:94-98:

markdown
| `POSTGRES_USER`       | `codai`          | Database user                  |
| `POSTGRES_PASSWORD`   | `pgpass`         | Database password              |
| `POSTGRES_MAIN_DB`    | `codai_main`     | Primary database name          |
markdown
- **Host**: `codai_postgres` (container name on shared network)
- **Port**: `5432`
- **User**: `codai` / **Password**: `pgpass`
- **DB**: `codai_main` (or instance-specific db)

Technical Analysis

The PostgreSQL container starts with the predictable credentials codai / pgpass whenever the operator does not define POSTGRES_USER and POSTGRES_PASSWORD. The shell script only prints a warning and does not reject the insecure password or prevent service startup.

The host port is limited to 127.0.0.1, reducing exposure to remote hosts. However, the service also joins the external shared Docker network named nginx-proxy_net by default. Containers attached to that network can reach PostgreSQL using codai_postgres:5432, bypassing the host loopback restriction. Because the documentation ...[truncated 1518 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the fallback password and require an explicitly supplied secret:

    yaml
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-codai}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
      POSTGRES_DB: ${POSTGRES_MAIN_DB:-codai_main}
    
  2. Make run.sh fail before invoking Docker if the password is absent, blank, or equal to a known default:

    bash
    : "${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}"
    if [ "$POSTGRES_PASSWORD" = "pgpass" ]; then
        echo "Error: the default PostgreSQL password is prohibited." >&2
        exit 1
    fi
    
  3. Supply the password through Docker secrets or another protected secret-management mechanism. Restrict permissions on any local environment file containing the secret and exclude it from version control.

  4. Rotate the password inside PostgreSQL for existing persistent volumes. Merely changing the Compose environment variable may not update credentials created during initial database initialization.

  5. Avoid attaching the database to a broadly shared network. Use a dedicated internal network and attach only containers that require database access.

  6. Apply least privilege by using separate application roles with access limited to their required databases and operations. Reserve administrative roles for management tasks.

  7. Remove working credentials from documentation and replace them with placeholders that clearly require operator-supplied values.

Vulnerability Patterns
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Shadow Command Trigger

Medium
Category
Trigger Abuse
Confidence
89% confidence
Finding

The trigger phrase 'start postgres' begins with a generic built-in verb and can shadow or be confused with a broader platform 'start' command, causing the wrong action to fire. In this skill, that action launches a Dockerized PostgreSQL service, so accidental invocation can start infrastructure, expose a local service, and consume resources without the user intending to invoke this specific skill.

Content

No source excerpt is available for this finding.

Shadow Command Trigger

Medium
Category
Trigger Abuse
Confidence
88% confidence
Finding

The trigger phrase 'stop postgres' similarly overlaps with a generic built-in 'stop' command and may intercept or be misrouted from a user's broader stop request. Because this skill manages shared local infrastructure, an unintended match could stop a running PostgreSQL container and disrupt dependent development environments or cause availability loss for other local instances.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This shell skill presents its description, usage instructions, warnings, and prompts exclusively in Portuguese. Under the policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The manifest describes lifecycle management, database creation/removal, and dumps, but the script also exposes a psql command that opens an interactive SQL shell inside the container. That grants general-purpose direct database access beyond the narrower management operations described in the manifest.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.