T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/process_and_send.sh:1
- Finding
- Predictable and Insecure Storage of Raw Email Content## Vulnerability Details **File Location**: `scripts/process_and_send.sh`, lines 1-7 **Vulnerability Type**: Predictable temporary file, unsafe file creation, and plaintext sensitive-data storage **Risk Level**: Medium ### Vulnerable Code ```bash EMAIL_DIGEST_DIR="memory/$(date +%Y-%m-%d)-email-digests" TEMP_EMAIL_FILE="${EMAIL_DIGEST_DIR}/raw_email_content.txt" TEMP_HTML_FILE="${EMAIL_DIGEST_DIR}/final_digest.html" mkdir -p "${EMAIL_DIGEST_DIR}" # --- Trap for cleanup on exit --- trap 'rm -f "${TEMP_EMAIL_FILE}" "${TEMP_HTML_FILE}"' EXIT # Save decoded email body to a temporary file for summarization script echo "$EMAIL_BODY_DECODED" > "${TEMP_EMAIL_FILE}" ``` ### Technical Analysis The script stores the complete decoded email in a deterministic path based only on the current date. It creates neither the directory nor the file with explicit restrictive permissions, so their accessibility depends on the process umask and the permissions of the working directory. Shell output redirection follows symbolic links and does not provide exclusive file creation. If another local user or process can write to the `memory` directory, it can predict the destination and pre-create `raw_email_content.txt` as a symbolic link. When the skill runs, the shell opens the linked target for truncation and writes the decoded email into it. The exit trap reduces retention after normal script termination, but it does not prevent disclosure while the script is running, protect against symbolic-link attacks, or guarantee cleanup after abrupt termination such as `SIGKILL`. The predictable `final_digest.html` path is subject to the same unsafe-file-creation design, although the shown script does not currently write that file. ### Attack Path 1. An attacker obtains local write access to the skill's working directory or its `memory` subdirectory. 2. The attacker predicts the directory name from the current date: `memory/YYYY-MM-DD-email-digests`. 3. Before the victim invokes th ...[truncated 1289 chars]
- Remediation
- ## Remediation Suggestions 1. Set a restrictive umask before creating any files containing email data: ```bash umask 077 ``` 2. Create a private, unpredictable temporary directory and clean up the entire directory: ```bash TEMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/email-news-digest.XXXXXXXX")" trap 'rm -rf -- "$TEMP_DIR"' EXIT TEMP_EMAIL_FILE="$TEMP_DIR/raw_email_content.txt" TEMP_HTML_FILE="$TEMP_DIR/final_digest.html" ``` 3. Create sensitive files with exclusive creation and mode `0600`. Do not reuse predictable paths or follow pre-existing symbolic links. 4. Prefer avoiding plaintext storage entirely. Pipe decoded content directly into the summarization process or provide it through standard input: ```bash printf '%s' "$RAW_MESSAGE_B64" | base64 -d | uv run "$SUMMARIZE_SCRIPT" ``` The Python script would need to read from standard input when no input file is supplied. 5. If persistent digest artifacts are required, create a dedicated directory owned by the executing account with mode `0700`, validate ownership before use, and generate unique filenames. 6. Avoid `echo` for arbitrary message content because option-like values and implementation-specific escape handling can alter data. Use `printf '%s' "$EMAIL_BODY_DECODED"` when file storage is unavoidable. 7. Remove the unnecessary `raw_summary` field from `scripts/summarize_content.py` unless callers explicitly require it, because it duplicates the complete source email in the generated JSON and shell memory.
