Skip to content

🛡️ Sentinel: [CRITICAL] Fix insecure temporary file usage#73

Open
kidchenko wants to merge 1 commit intomainfrom
sentinel/fix-insecure-tmp-downloads-16156909619627972950
Open

🛡️ Sentinel: [CRITICAL] Fix insecure temporary file usage#73
kidchenko wants to merge 1 commit intomainfrom
sentinel/fix-insecure-tmp-downloads-16156909619627972950

Conversation

@kidchenko
Copy link
Copy Markdown
Owner

@kidchenko kidchenko commented Mar 29, 2026

🚨 Severity: CRITICAL
💡 Vulnerability: Insecure temporary file usage (CWE-377/CWE-362). The script tools/os_installers/apt.sh downloaded files (e.g., yq) directly to a predictable path in a world-writable directory (/tmp/yq) before executing sudo mv and sudo chmod.
🎯 Impact: A local attacker could pre-create the predictable file or create a symlink at /tmp/yq. When the script executes, it would overwrite the attacker-controlled location or execute malicious code with elevated privileges, leading to local privilege escalation.
🔧 Fix: Replaced hardcoded and predictable paths with securely generated temporary directories using mktemp -d. Each tool installation was wrapped in a subshell (...) with a local trap 'rm -rf "$TMP_DIR"' EXIT to ensure clean up. This was applied to yq, Go, lsd, and Composer downloads.
✅ Verification: Review the changes in tools/os_installers/apt.sh to ensure mktemp -d is used. Run ./build.sh to verify syntax and linting checks pass.


PR created automatically by Jules for task 16156909619627972950 started by @kidchenko

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced installation security for Go, yq, lsd, and Composer packages by implementing secure temporary directory handling with automatic cleanup.
  • Documentation

    • Added security documentation and guidance on secure temporary directory practices.

Replaced hardcoded and predictable temporary paths (e.g., /tmp/yq) with securely generated temporary directories using `mktemp -d`. This prevents symlink attacks and arbitrary file overwrites when downloading tools in `apt.sh`. Additionally, encapsulated each download block in a subshell with a localized cleanup trap to ensure directories are removed without affecting global script state.

Signed-off-by: Sentinel <sentinel@example.com>

Co-authored-by: kidchenko <5432753+kidchenko@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 29, 2026

📝 Walkthrough

Walkthrough

A security-focused refactor replaces hardcoded and predictable temporary file paths in installer scripts with securely generated temporary directories, paired with trap handlers to ensure cleanup on exit. Documentation describing the vulnerability is added.

Changes

Cohort / File(s) Summary
Security Documentation
.jules/sentinel.md
New documentation entry describing a security vulnerability involving hardcoded temporary paths (e.g., /tmp/yq), including the attack mechanism and mitigation guidance using mktemp -d and trap handlers.
Installation Script Security Hardening
tools/os_installers/apt.sh
Refactored Go, yq, lsd, and Composer installations to use secure temporary directories (mktemp -d) with trap-based cleanup on EXIT. Replaced hardcoded paths and working directory file creation with per-install temp directories; Composer also now validates checksums from the temp path before installation.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

🐰 With whiskers twitching, I hop with glee,
No more /tmp paths for all to see!
Temp folders spawned, then cleaned away,
Security strengthens with each new day! 🛡️✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title references a critical security fix for insecure temporary file usage, which is the main change in the pull request.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sentinel/fix-insecure-tmp-downloads-16156909619627972950

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.jules/sentinel.md:
- Around line 1-4: Change the first line to a top-level heading (replace leading
"##" with "#") and insert a blank line after that heading to satisfy MD041 and
MD022; then reflow the subsequent paragraph lines to be <=80 characters each
(wrap the long sentence about vulnerability/learning/prevention into multiple
shorter lines) so MD013 is fixed; reference the heading text "2024-05-24 -
[Avoid predictable temporary paths in shared locations like /tmp]" when updating
.jules/sentinel.md.

In `@tools/os_installers/apt.sh`:
- Around line 272-276: The else branch that handles the checksum mismatch
currently only echoes an error and returns a zero exit status; update the
checksum verification block that compares EXPECTED_CHECKSUM and ACTUAL_CHECKSUM
to terminate the script with a non-zero status on failure by adding an explicit
exit 1 after the error message so the installer does not continue silently
(affecting the branch that would otherwise run sudo php
"$COMPOSER_TMP_DIR/composer-setup.php" --quiet --install-dir=/usr/local/bin
--filename=composer).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e11643a6-d049-4b31-b2c1-7d1dab02a5dd

📥 Commits

Reviewing files that changed from the base of the PR and between eb5ca40 and 0d07a98.

📒 Files selected for processing (2)
  • .jules/sentinel.md
  • tools/os_installers/apt.sh

Comment on lines +1 to +4
## 2024-05-24 - [Avoid predictable temporary paths in shared locations like /tmp]
**Vulnerability:** A script uses a hardcoded, predictable path (e.g., `/tmp/yq`) when downloading tools, which could lead to a symlink attack or unauthorized file modification, especially when running with elevated privileges (like `sudo mv /tmp/yq /usr/local/bin/yq`).
**Learning:** Hardcoding paths in world-writable directories (`/tmp`) makes the script vulnerable to a local attacker pre-creating the file (or a symlink) to perform malicious actions.
**Prevention:** Always use securely generated temporary directories (e.g., `mktemp -d`) coupled with a cleanup trap to store downloaded files before moving them to their final destination.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix markdown linting errors to pass CI.

The pipeline reports several markdownlint failures:

  1. MD041: First line should be a top-level heading (# instead of ##)
  2. MD022: Add a blank line after the heading
  3. MD013: Lines 2-4 exceed the 80-character limit
Proposed fix
-## 2024-05-24 - [Avoid predictable temporary paths in shared locations like /tmp]
-**Vulnerability:** A script uses a hardcoded, predictable path (e.g., `/tmp/yq`) when downloading tools, which could lead to a symlink attack or unauthorized file modification, especially when running with elevated privileges (like `sudo mv /tmp/yq /usr/local/bin/yq`).
-**Learning:** Hardcoding paths in world-writable directories (`/tmp`) makes the script vulnerable to a local attacker pre-creating the file (or a symlink) to perform malicious actions.
-**Prevention:** Always use securely generated temporary directories (e.g., `mktemp -d`) coupled with a cleanup trap to store downloaded files before moving them to their final destination.
+# Sentinel Security Learnings
+
+## 2024-05-24 - Avoid predictable temporary paths in /tmp
+
+**Vulnerability:** A script uses a hardcoded, predictable path (e.g.,
+`/tmp/yq`) when downloading tools, which could lead to a symlink attack or
+unauthorized file modification, especially when running with elevated
+privileges (like `sudo mv /tmp/yq /usr/local/bin/yq`).
+
+**Learning:** Hardcoding paths in world-writable directories (`/tmp`) makes
+the script vulnerable to a local attacker pre-creating the file (or a
+symlink) to perform malicious actions.
+
+**Prevention:** Always use securely generated temporary directories (e.g.,
+`mktemp -d`) coupled with a cleanup trap to store downloaded files before
+moving them to their final destination.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## 2024-05-24 - [Avoid predictable temporary paths in shared locations like /tmp]
**Vulnerability:** A script uses a hardcoded, predictable path (e.g., `/tmp/yq`) when downloading tools, which could lead to a symlink attack or unauthorized file modification, especially when running with elevated privileges (like `sudo mv /tmp/yq /usr/local/bin/yq`).
**Learning:** Hardcoding paths in world-writable directories (`/tmp`) makes the script vulnerable to a local attacker pre-creating the file (or a symlink) to perform malicious actions.
**Prevention:** Always use securely generated temporary directories (e.g., `mktemp -d`) coupled with a cleanup trap to store downloaded files before moving them to their final destination.
# Sentinel Security Learnings
## 2024-05-24 - Avoid predictable temporary paths in /tmp
**Vulnerability:** A script uses a hardcoded, predictable path (e.g.,
`/tmp/yq`) when downloading tools, which could lead to a symlink attack or
unauthorized file modification, especially when running with elevated
privileges (like `sudo mv /tmp/yq /usr/local/bin/yq`).
**Learning:** Hardcoding paths in world-writable directories (`/tmp`) makes
the script vulnerable to a local attacker pre-creating the file (or a
symlink) to perform malicious actions.
**Prevention:** Always use securely generated temporary directories (e.g.,
`mktemp -d`) coupled with a cleanup trap to store downloaded files before
moving them to their final destination.
🧰 Tools
🪛 GitHub Check: Lint Documentation

[failure] 4-4: Line length
.jules/sentinel.md:4:81 MD013/line-length Line length [Expected: 80; Actual: 188] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md


[failure] 3-3: Line length
.jules/sentinel.md:3:81 MD013/line-length Line length [Expected: 80; Actual: 184] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md


[failure] 2-2: Line length
.jules/sentinel.md:2:81 MD013/line-length Line length [Expected: 80; Actual: 269] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md


[failure] 1-1: First line in a file should be a top-level heading
.jules/sentinel.md:1 MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "## 2024-05-24 - [Avoid predict..."] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md041.md


[failure] 1-1: Headings should be surrounded by blank lines
.jules/sentinel.md:1 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## 2024-05-24 - [Avoid predictable temporary paths in shared locations like /tmp]"] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.jules/sentinel.md around lines 1 - 4, Change the first line to a top-level
heading (replace leading "##" with "#") and insert a blank line after that
heading to satisfy MD041 and MD022; then reflow the subsequent paragraph lines
to be <=80 characters each (wrap the long sentence about
vulnerability/learning/prevention into multiple shorter lines) so MD013 is
fixed; reference the heading text "2024-05-24 - [Avoid predictable temporary
paths in shared locations like /tmp]" when updating .jules/sentinel.md.

Comment on lines +272 to +276
if [ "$EXPECTED_CHECKSUM" = "$ACTUAL_CHECKSUM" ]; then
sudo php "$COMPOSER_TMP_DIR/composer-setup.php" --quiet --install-dir=/usr/local/bin --filename=composer
else
>&2 echo 'ERROR: Invalid installer checksum for Composer'
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add exit 1 after checksum mismatch error.

When the checksum validation fails, the script prints an error but the subshell exits with code 0 (from the successful echo). This means the overall script continues silently without installing Composer, which could mask a security issue.

Proposed fix
         if [ "$EXPECTED_CHECKSUM" = "$ACTUAL_CHECKSUM" ]; then
             sudo php "$COMPOSER_TMP_DIR/composer-setup.php" --quiet --install-dir=/usr/local/bin --filename=composer
         else
             >&2 echo 'ERROR: Invalid installer checksum for Composer'
+            exit 1
         fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [ "$EXPECTED_CHECKSUM" = "$ACTUAL_CHECKSUM" ]; then
sudo php "$COMPOSER_TMP_DIR/composer-setup.php" --quiet --install-dir=/usr/local/bin --filename=composer
else
>&2 echo 'ERROR: Invalid installer checksum for Composer'
fi
if [ "$EXPECTED_CHECKSUM" = "$ACTUAL_CHECKSUM" ]; then
sudo php "$COMPOSER_TMP_DIR/composer-setup.php" --quiet --install-dir=/usr/local/bin --filename=composer
else
>&2 echo 'ERROR: Invalid installer checksum for Composer'
exit 1
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/os_installers/apt.sh` around lines 272 - 276, The else branch that
handles the checksum mismatch currently only echoes an error and returns a zero
exit status; update the checksum verification block that compares
EXPECTED_CHECKSUM and ACTUAL_CHECKSUM to terminate the script with a non-zero
status on failure by adding an explicit exit 1 after the error message so the
installer does not continue silently (affecting the branch that would otherwise
run sudo php "$COMPOSER_TMP_DIR/composer-setup.php" --quiet
--install-dir=/usr/local/bin --filename=composer).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant