T09 · Insecure Skill Coding Practices
- Location
scripts/compress_image.sh:43- Finding
Destructive In-Place Compression of Files Already Marked as Compressed
- Content
View full analysis
Vulnerability Details
File Location:
scripts/compress_image.sh, lines 43–66
Vulnerability Type: Unsafe output-path handling and unintended file overwrite
Risk Level: MediumVulnerable Code:
bash # 生成压缩后的文件名 if [[ "$FILE_NAME" =~ .*_compressed\..* ]]; then OUTPUT_PATH="$IMAGE_PATH" else OUTPUT_NAME="${FILE_NAME%.*}_compressed.${FILE_EXT}" OUTPUT_PATH="${FILE_DIR}/${OUTPUT_NAME}" fi # 压缩图片 if [ "$FILE_EXT" = "png" ]; then # PNG 压缩 sips -Z "$MAX_WIDTH" "$IMAGE_PATH" --out "$OUTPUT_PATH" # PNG 优化(使用 optipng) if command -v optipng >/dev/null 2>&1; then optipng -o2 -q "$OUTPUT_PATH" fi elif [ "$FILE_EXT" = "gif" ]; then # GIF 压缩 sips -Z "$MAX_WIDTH" "$IMAGE_PATH" --out "$OUTPUT_PATH" else # 其他格式(JPEG) sips -Z "$MAX_WIDTH" -s formatOptions "${QUALITY}%" "$IMAGE_PATH" --out "$OUTPUT_PATH" fiTechnical Analysis
When the input filename contains
_compressed.anywhere in its name, the script setsOUTPUT_PATHto the same path asIMAGE_PATH. It then supplies that path tosipsas both the input file and the--outdestination.This creates a destructive in-place processing condition rather than generating a separate output file. It also contradicts the documented behavior that the original file is preserved. Because no source/destination equality check, temporary output file, backup, or atomic replacement mechanism is used, an existing image may be overwritten, degraded, or left unusable if processing fails partway through.
The filename test is also broad: it matches any filename containing
_compressed.rather than reliably identifying and safely handling an output generated during the current operation.Attack Path
- An attacker supplies, creates, or persuades a user to process an image larger than the configured compression threshold.
- The image is named with the matching pattern, such as ` ...[truncated 1032 chars]
- Remediation
View remediation
Remediation Suggestions
- Always create an output path that differs from the input path, regardless of whether the filename already contains
_compressed. - Explicitly compare canonical source and destination paths and abort if they are identical.
- Generate a collision-resistant output name when the intended destination already exists, or require explicit user confirmation before replacing it.
- Write compressed data to a securely created temporary file in the destination directory.
- Verify that the compression command succeeds and that the temporary output is a valid, nonempty image before moving it into place.
- Use an atomic rename only after successful validation.
- Reject symbolic links where they are not required, or resolve and validate them before writing.
- Check the exit status of
sipsandoptipnginstead of treating the mere existence of the output path as proof of success. - Preserve the original file by default and document any optional overwrite behavior explicitly.
A safe implementation should follow this sequence: derive a distinct destination, create a secure temporary file, compress into that file, validate the command result and output, and atomically rename it to the final destination without modifying the source.
- Always create an output path that differs from the input path, regardless of whether the filename already contains
