T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/qa-check.sh:18
- Finding
- Predictable Temporary Build Log Enables Symlink and Race Attacks<![CDATA[ ## Vulnerability Details **File Location**: `scripts/qa-check.sh`, lines 18–26 **Vulnerability Type**: Predictable temporary file / insecure temporary-file handling **Risk Level**: Medium ### Vulnerable Code ```bash if npm run build 2>&1 | tee /tmp/build.log; then echo "✅ Build passed" ((PASSED++)) else echo "❌ Build FAILED" ((FAILED++)) fi # 2. Check for common issues in build output echo "" echo "2️⃣ Checking for warnings..." if grep -i "warning" /tmp/build.log | grep -v "node_modules" | head -5; then ``` ### Technical Analysis The script stores build output in the fixed, globally predictable path `/tmp/build.log`. Files under `/tmp` are normally accessible to multiple local users and processes. The `tee` command opens its destination for writing and follows symbolic links by default. An attacker with local access can create `/tmp/build.log` as a symbolic link to another file before the QA script runs. When the script executes `tee /tmp/build.log`, it follows that link and truncates or overwrites the linked target with build output, provided the account running the script has permission to write to that target. The same fixed path is also shared by every concurrent execution. One run can overwrite another run's output between the build and warning checks, causing inaccurate QA results. Depending on system permissions, build output may also be exposed to other local users. ### Attack Path 1. An attacker obtains local access to the host or otherwise gains the ability to create entries in `/tmp`. 2. The attacker removes any existing `/tmp/build.log` and replaces it with a symbolic link: ```bash ln -s /path/to/victim-writable-file /tmp/build.log ``` 3. A victim runs `scripts/qa-check.sh` under an account that can write to the linked target. 4. The `tee` process follows the symbolic link and opens the target for writing. 5. The target is truncated and replaced with captured build output. 6. Alternatively, the attacker or ...[truncated 1192 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Create a unique temporary file securely with `mktemp`, restrict its permissions, clean it up automatically, and use the generated path consistently: ```bash BUILD_LOG="$(mktemp "${TMPDIR:-/tmp}/qa-check-build.XXXXXX")" || { echo "Unable to create a secure temporary build log" >&2 exit 1 } chmod 600 "$BUILD_LOG" trap 'rm -f -- "$BUILD_LOG"' EXIT HUP INT TERM if npm run build 2>&1 | tee "$BUILD_LOG"; then echo "✅ Build passed" ((PASSED++)) else echo "❌ Build FAILED" ((FAILED++)) fi if grep -i "warning" "$BUILD_LOG" | grep -v "node_modules" | head -5; then echo "⚠️ Warnings found (review above)" else echo "✅ No critical warnings" ((PASSED++)) fi ``` Additional hardening measures: 1. Do not execute the QA script as `root` or another privileged account. 2. Quote every reference to the generated temporary path. 3. Use a cleanup trap so the temporary file is removed on normal exit and interruption. 4. Keep build logs private with mode `0600`. 5. If persistent logs are required, place them in a dedicated per-user directory with restrictive ownership and permissions rather than a shared `/tmp` filename. ]]>
