T09 · Insecure Skill Coding Practices
- Location
run.sh:26- Finding
Predictable Backup Filename Allows Symlink-Based File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
run.sh, lines 26-30
Vulnerability Type: Predictable file creation and unsafe handling of an existing destination
Risk Level: MediumVulnerable Code
bash BASENAME=$(basename "$FILE_PATH") TIMESTAMP=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="$BACKUP_DIR/${BASENAME}.backup_${TIMESTAMP}" cp "$FILE_PATH" "$BACKUP_FILE"Technical Analysis
The backup filename is derived from the source basename and a timestamp with one-second precision. The resulting path is predictable, and the script neither atomically reserves the destination nor verifies that it does not already exist or refer to a symbolic link.
If the selected backup directory is writable by another user, that user can predict the destination and create it as a symbolic link before
cpexecutes. A normalcpoperation can follow an existing destination symlink and write the source data to its target. The target must still be writable by the account running the script, so this issue does not independently bypass operating-system permissions.The same naming scheme also causes two backups of the same source basename created within one second to use the same destination. The later operation can silently overwrite the earlier backup.
Attack Path
- A victim invokes
run.shwith a shared or attacker-writable directory asBACKUP_DIR. - The attacker learns or predicts the source basename and the second in which the script will run.
- The attacker creates the anticipated backup path, such as
config.yaml.backup_20260328_143022, as a symbolic link to another file. - The script constructs the same predictable destination without checking whether it already exists or is a symlink.
cpwrites through the destination symlink and replaces the target's contents with the source file, provided the victim's account can write to that target.
Exploitation therefore requires control of the backup director ...[truncated 665 chars]
- A victim invokes
- Remediation
View remediation
Remediation Suggestions
- Atomically create a unique destination inside the selected backup directory using
mktemp, rather than constructing a predictable name and subsequently opening it. - Ensure the temporary destination is created in
BACKUP_DIRitself so uniqueness and creation occur on the intended filesystem. - Reject unsafe backup directories, particularly directories writable by untrusted users, or explicitly document that such directories must not be used.
- If a human-readable final name is required, reserve it atomically and fail rather than overwrite when it already exists. Do not use a check-then-copy sequence because it remains vulnerable to a time-of-check/time-of-use race.
- Apply restrictive permissions appropriate for potentially sensitive source files and preserve the desired source metadata deliberately.
- Add tests covering pre-existing files, destination symlinks, concurrent invocations, and multiple backups created within the same second.
A hardened implementation should use an atomically generated path, for example:
bash BASENAME=$(basename -- "$FILE_PATH") BACKUP_FILE=$(mktemp --tmpdir="$BACKUP_DIR" "${BASENAME}.backup_$(date +%Y%m%d_%H%M%S).XXXXXX") chmod --reference="$FILE_PATH" "$BACKUP_FILE" cp -- "$FILE_PATH" "$BACKUP_FILE"Where supported, use copy options and file-creation APIs that explicitly reject symlink destinations and prevent clobbering. Any failure after reserving the file should also remove the incomplete backup.
- Atomically create a unique destination inside the selected backup directory using
