docker [postgres] create new scripts#209
Conversation
| # ============================================================================= | ||
|
|
||
| print_info "Connecting to database \"$POSTGRES_DB\" as user \"$POSTGRES_USER\"..." | ||
| docker exec -it pneumatic-postgres sh -c "PGPASSWORD=$POSTGRES_PASSWORD psql -U $POSTGRES_USER $POSTGRES_DB" |
There was a problem hiding this comment.
🟠 High scripts/postgres_terminal.sh:52
Line 52 interpolates $POSTGRES_PASSWORD, $POSTGRES_USER, and $POSTGRES_DB directly into a sh -c "..." command string. Because the outer quotes are double quotes, shell metacharacters in these values (e.g., $, backticks, ;, spaces) are interpreted by the inner shell rather than treated literally. For example, a password like p@ss$word causes $word to expand to empty string, resulting in PGPASSWORD=p@ss. A password like p;rm -rf / would execute rm -rf / inside the container. Even common special characters in database credentials will cause silent credential mangling or command injection. Consider passing the password via docker exec -e and dropping the sh -c wrapper so values are passed as literals.
-docker exec -it pneumatic-postgres sh -c "PGPASSWORD=$POSTGRES_PASSWORD psql -U $POSTGRES_USER $POSTGRES_DB"
+docker exec -e "PGPASSWORD=$POSTGRES_PASSWORD" -it pneumatic-postgres psql -U "$POSTGRES_USER" "$POSTGRES_DB"Also found in 1 other location(s)
scripts/restore_backup.sh:183
On line 183, the variables
$POSTGRES_PASSWORD,$POSTGRES_USER,$POSTGRES_HOST,$POSTGRES_DB, and$BACKUP_FILENAMEare expanded by the outer shell into thesh -cstring without any escaping. If any of these values contain shell metacharacters (spaces, quotes, semicolons, backticks,$, etc.), the innersh -ccommand will misinterpret them, potentially causing command injection or command failure. Passwords are especially likely to contain special characters. The same issue affects lines 148, 164, and 173.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file scripts/postgres_terminal.sh around line 52:
Line 52 interpolates `$POSTGRES_PASSWORD`, `$POSTGRES_USER`, and `$POSTGRES_DB` directly into a `sh -c "..."` command string. Because the outer quotes are double quotes, shell metacharacters in these values (e.g., `$`, backticks, `;`, spaces) are interpreted by the inner shell rather than treated literally. For example, a password like `p@ss$word` causes `$word` to expand to empty string, resulting in `PGPASSWORD=p@ss`. A password like `p;rm -rf /` would execute `rm -rf /` inside the container. Even common special characters in database credentials will cause silent credential mangling or command injection. Consider passing the password via `docker exec -e` and dropping the `sh -c` wrapper so values are passed as literals.
Also found in 1 other location(s):
- scripts/restore_backup.sh:183 -- On line 183, the variables `$POSTGRES_PASSWORD`, `$POSTGRES_USER`, `$POSTGRES_HOST`, `$POSTGRES_DB`, and `$BACKUP_FILENAME` are expanded by the outer shell into the `sh -c` string without any escaping. If any of these values contain shell metacharacters (spaces, quotes, semicolons, backticks, `$`, etc.), the inner `sh -c` command will misinterpret them, potentially causing command injection or command failure. Passwords are especially likely to contain special characters. The same issue affects lines 148, 164, and 173.
| key=$(echo "$key" | xargs) | ||
| value=$(echo "$value" | xargs) |
There was a problem hiding this comment.
🟡 Medium scripts/postgres_terminal.sh:36
On lines 36-37, echo "$value" | xargs trims whitespace but also interprets quotes and backslashes in the .env value. A password like p@ss'w"ord or p@ss\word gets mangled or causes xargs: unmatched single quote, corrupting credentials and causing silent connection failures. Consider using sed 's/^[[:space:]]*//;s/[[:space:]]*$//' to trim without shell metacharacter interpretation.
- key=$(echo "$key" | xargs)
- value=$(echo "$value" | xargs)
+ key=$(echo "$key" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
+ value=$(echo "$value" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file scripts/postgres_terminal.sh around lines 36-37:
On lines 36-37, `echo "$value" | xargs` trims whitespace but also interprets quotes and backslashes in the `.env` value. A password like `p@ss'w"ord` or `p@ss\word` gets mangled or causes `xargs: unmatched single quote`, corrupting credentials and causing silent connection failures. Consider using `sed 's/^[[:space:]]*//;s/[[:space:]]*$//'` to trim without shell metacharacter interpretation.
| while IFS='=' read -r key value; do | ||
| key=$(echo "$key" | xargs) | ||
| value=$(echo "$value" | xargs) |
There was a problem hiding this comment.
🟢 Low scripts/restore_backup.sh:86
The .env parsing loop on lines 86-96 does not skip comment lines (starting with #) or blank lines. When the .env file contains comments like # Database config, the IFS='=' read assigns the entire line to key, and xargs processes it. While this won't match any case branch, comments containing special characters cause xargs to fail with errors like "xargs: unmatched single quote" or similar shell parsing failures, breaking the script.
-while IFS='=' read -r key value; do
+while IFS='=' read -r key value || [ -n "$key" ]; do
+ # Skip comment lines and blank lines
+ [[ "$key" =~ ^[[:space:]]*# ]] && continue
+ [[ -z "$key" ]] && continue
+
key=$(echo "$key" | xargs)
value=$(echo "$value" | xargs)🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file scripts/restore_backup.sh around lines 86-88:
The `.env` parsing loop on lines 86-96 does not skip comment lines (starting with `#`) or blank lines. When the `.env` file contains comments like `# Database config`, the `IFS='=' read` assigns the entire line to `key`, and `xargs` processes it. While this won't match any `case` branch, comments containing special characters cause `xargs` to fail with errors like "xargs: unmatched single quote" or similar shell parsing failures, breaking the script.
| case "$COMPOSE_FILE" in | ||
| 1) | ||
| output=$(docker compose -f "$PROJECT_DIR/docker-compose.yml" up -d 2>&1) | ||
| ;; | ||
| 2) | ||
| output=$(TAG=latest docker compose -f "$PROJECT_DIR/docker-compose.yml" up -d 2>&1) | ||
| ;; | ||
| 3) | ||
| output=$(docker compose -f "$PROJECT_DIR/docker-compose.src.yml" up -d 2>&1) | ||
| ;; | ||
| 4) | ||
| output=$(docker compose -f "$PROJECT_DIR/frontend/docker-compose.yml" up -d 2>&1) | ||
| ;; | ||
| 5) | ||
| output=$(docker compose -f "$PROJECT_DIR/backend/docker-compose.yml" up -d 2>&1) | ||
| ;; | ||
| esac |
There was a problem hiding this comment.
🔴 Critical scripts/restore_backup.sh:226
The docker-compose configuration selector labels are swapped. Option 1 "Root (latest)" runs without setting TAG, so it deploys the stable default. Option 2 "Root (stable)" sets TAG=latest, so it deploys latest images. Users selecting "stable" get "latest" and vice versa.
case "$COMPOSE_FILE" in
1)
- output=$(docker compose -f "$PROJECT_DIR/docker-compose.yml" up -d 2>&1)
+ output=$(TAG=latest docker compose -f "$PROJECT_DIR/docker-compose.yml" up -d 2>&1)
;;
2)
- output=$(TAG=latest docker compose -f "$PROJECT_DIR/docker-compose.yml" up -d 2>&1)
+ output=$(docker compose -f "$PROJECT_DIR/docker-compose.yml" up -d 2>&1)
;;🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file scripts/restore_backup.sh around lines 226-242:
The docker-compose configuration selector labels are swapped. Option 1 "Root (latest)" runs without setting `TAG`, so it deploys the `stable` default. Option 2 "Root (stable)" sets `TAG=latest`, so it deploys `latest` images. Users selecting "stable" get "latest" and vice versa.
| MAX_RETRIES=30 | ||
| RETRY_COUNT=0 | ||
| while true; do | ||
| docker exec -it pneumatic-postgres sh -c "pg_isready -U $POSTGRES_USER -h $POSTGRES_HOST" > /dev/null 2>&1 |
There was a problem hiding this comment.
🟠 High scripts/restore_backup.sh:148
Lines 148, 164, 173, and 183 use docker exec -it with TTY allocation inside $(...) command substitutions where stdout is captured, not a terminal. On many Docker versions, -t without a real TTY produces "the input device is not a TTY" and causes the command to fail or inject \r carriage returns into $output, breaking the $? check or corrupting error messages. Remove -t from these docker exec calls.
- docker exec -it pneumatic-postgres sh -c "pg_isready -U $POSTGRES_USER -h $POSTGRES_HOST" > /dev/null 2>&1
+ docker exec -i pneumatic-postgres sh -c "pg_isready -U $POSTGRES_USER -h $POSTGRES_HOST" > /dev/null 2>&1🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file scripts/restore_backup.sh around line 148:
Lines 148, 164, 173, and 183 use `docker exec -it` with TTY allocation inside `$(...)` command substitutions where stdout is captured, not a terminal. On many Docker versions, `-t` without a real TTY produces "the input device is not a TTY" and causes the command to fail or inject `\r` carriage returns into `$output`, breaking the `$?` check or corrupting error messages. Remove `-t` from these `docker exec` calls.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 47a8eca. Configure here.
| print_info "Select a docker-compose configuration to start containers:" | ||
| echo "" | ||
| echo " 1. Root (latest)" | ||
| echo " 2. Root (stable)" |
There was a problem hiding this comment.
Swapped labels for "latest" and "stable" compose options
High Severity
The menu labels "Root (latest)" and "Root (stable)" are swapped relative to their actual behavior. Option 1 ("latest") runs docker-compose.yml without setting TAG, which defaults to stable via ${TAG:-stable}. Option 2 ("stable") explicitly sets TAG=latest. A user choosing "stable" will get latest images, and vice versa — risking unintended deployments after a database restore.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 47a8eca. Configure here.


…backup.sh"
Note
Medium Risk
Adds interactive scripts that stop containers and drop/recreate the configured Postgres database during restore; misuse or misconfiguration could cause accidental data loss in local/dev environments.
Overview
Adds two new utility scripts for local Docker Postgres workflows.
scripts/postgres_terminal.shopens an interactivepsqlsession inside thepneumatic-postgrescontainer using connection settings read from.env.scripts/restore_backup.shintroduces an interactive restore flow: lists backups frompostgres/backups, confirms overwrite, restarts containers, waits for Postgres readiness, drops/recreates the target database, restores the selected SQL file into the container, then restarts services based on a user-selected compose configuration.Reviewed by Cursor Bugbot for commit 47a8eca. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add postgres terminal and backup restore scripts for Docker
.envand opens an interactivepsqlsession inside thepneumatic-postgrescontainer.psql, then restarts project containers using a user-selecteddocker-composeconfiguration.docker compose down.📊 Macroscope summarized 47a8eca. 2 files reviewed, 7 issues evaluated, 1 issue filtered, 5 comments posted
🗂️ Filtered Issues
scripts/restore_backup.sh — 3 comments posted, 5 evaluated, 1 filtered
$POSTGRES_PASSWORD,$POSTGRES_USER,$POSTGRES_HOST,$POSTGRES_DB, and$BACKUP_FILENAMEare expanded by the outer shell into thesh -cstring without any escaping. If any of these values contain shell metacharacters (spaces, quotes, semicolons, backticks,$, etc.), the innersh -ccommand will misinterpret them, potentially causing command injection or command failure. Passwords are especially likely to contain special characters. The same issue affects lines 148, 164, and 173. [ Cross-file consolidated ]