T09 · Insecure Skill Coding Practices
- 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: Highyaml 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." fiThe working default credentials are also disclosed in
SKILL.md:84-88andSKILL.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/pgpasswhenever the operator does not definePOSTGRES_USERandPOSTGRES_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 namednginx-proxy_netby default. Containers attached to that network can reach PostgreSQL usingcodai_postgres:5432, bypassing the host loopback restriction. Because the documentation ...[truncated 1518 chars]- Remediation
View remediation
Remediation Suggestions
-
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} -
Make
run.shfail 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 -
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.
-
Rotate the password inside PostgreSQL for existing persistent volumes. Merely changing the Compose environment variable may not update credentials created during initial database initialization.
-
Avoid attaching the database to a broadly shared network. Use a dedicated internal network and attach only containers that require database access.
-
Apply least privilege by using separate application roles with access limited to their required databases and operations. Reserve administrative roles for management tasks.
-
Remove working credentials from documentation and replace them with placeholders that clearly require operator-supplied values.
-
