T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/deploy.sh:107
- Finding
- Predictable Hardcoded PostgreSQL Credentials in Generated Docker Compose Configuration## Vulnerability Details **File Location**: `scripts/deploy.sh`, lines 107 and 120–123 **Vulnerability Type**: Hardcoded credentials in generated deployment configuration **Risk Level**: Medium ### Vulnerable Code ```yaml environment: - NODE_ENV=production - DATABASE_URL=postgres://user:pass@db:5432/appdb - REDIS_URL=redis://redis:6379 ``` ```yaml db: image: postgres:15-alpine environment: POSTGRES_USER: user POSTGRES_PASSWORD: pass POSTGRES_DB: appdb ``` ### Technical Analysis The `compose` command generates a functional Docker Compose configuration containing the fixed PostgreSQL username `user` and password `pass`. The same credentials are embedded in the application's `DATABASE_URL`, making the predictable secret available both in the generated configuration and in the application container's environment. These are not merely nonfunctional placeholders: deploying the generated configuration creates a PostgreSQL account using the published values. Although the provided Compose template does not directly publish PostgreSQL's port to the host, any process with access to the Compose network—including a compromised application or peer container—can attempt authentication using these known credentials. Users may also expose the database later without recognizing that the template contains insecure defaults. ### Attack Path 1. A user generates a Compose configuration with `bash scripts/deploy.sh compose <type>`. 2. The user deploys the generated configuration without replacing the default credentials. 3. An attacker compromises an Internet-facing application or another container attached to `app-network`, or reaches PostgreSQL after a later configuration change exposes port 5432. 4. The attacker connects to the `db` service using username `user`, password `pass`, and database `appdb`. 5. The attacker reads, modifies, or deletes data available to tha ...[truncated 753 chars]
- Remediation
- ## Remediation Suggestions - Remove all functional default passwords from the generated configuration. - Require explicit secret values using mandatory Compose interpolation: ```yaml services: app: environment: DATABASE_URL: "postgres://${POSTGRES_USER:?required}:${POSTGRES_PASSWORD:?required}@db:5432/${POSTGRES_DB:?required}" db: environment: POSTGRES_USER: "${POSTGRES_USER:?required}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:?required}" POSTGRES_DB: "${POSTGRES_DB:?required}" ``` - Prefer Docker secrets or an external secret manager for production deployments rather than storing credentials in source-controlled Compose files. - Add documentation warning users not to commit `.env` files and provide a `.env.example` containing names only, without usable credentials. - Generate a high-entropy password when an explicitly requested local-development mode needs automatic setup, and clearly distinguish that mode from production templates. - Keep PostgreSQL isolated on an internal network and do not publish port 5432 unless operationally necessary. - Rotate the database credentials in any environment already deployed from this template.
