Skip to content

🛡️ Sentinel: [HIGH] Fix local privilege escalation / symlink vulnerability in apt.sh#70

Open
kidchenko wants to merge 1 commit intomainfrom
sentinel/fix-insecure-temp-downloads-2822382016456990647
Open

🛡️ Sentinel: [HIGH] Fix local privilege escalation / symlink vulnerability in apt.sh#70
kidchenko wants to merge 1 commit intomainfrom
sentinel/fix-insecure-temp-downloads-2822382016456990647

Conversation

@kidchenko
Copy link
Copy Markdown
Owner

@kidchenko kidchenko commented Mar 26, 2026

🚨 Severity: HIGH
💡 Vulnerability: Predictable temporary file paths and downloading binaries to the current working directory. The tools/os_installers/apt.sh script downloaded files to locations like /tmp/yq or directly to . before using sudo dpkg -i or sudo mv on them. This creates a Time-of-Check to Time-of-Use (TOCTOU) vulnerability where a malicious user could pre-create a symlink at /tmp/yq pointing to a sensitive system file, or trick the script into overwriting local files, leading to privilege escalation when sudo is executed.
🎯 Impact: Local privilege escalation or denial of service by overwriting system binaries or arbitrary files owned by root.
🔧 Fix: Introduced a secure, isolated temporary directory using TMP_DIR=$(mktemp -d) at the start of the script. All vulnerable downloads (go, yq, lsd, composer) have been updated to target this secure directory. An EXIT trap was added to ensure the temporary directory is cleanly removed when the script finishes.
Verification: Run ./build.sh syntax to verify bash syntax. The script now safely downloads and cleans up artifacts without relying on shared, predictable directories. Also added a learning to .jules/sentinel.md.


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

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Enhanced installer script security by implementing isolated temporary directories for all downloaded binaries and installation artifacts, replacing use of predictable system paths.
  • Documentation

    • Added security vulnerability documentation detailing insecure temporary file handling patterns in setup scripts with prevention approaches and best practices.

Creates a secure temporary directory (`mktemp -d`) for downloading utilities
like Go, yq, and lsd instead of using the current working directory or
predictable paths like `/tmp/yq`, preventing symlink attacks and unintended
file overwriting.

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 26, 2026

📝 Walkthrough

Walkthrough

Added security documentation for download-path vulnerabilities in shell scripts, and refactored an OS installer script to download artifacts into secure temporary directories instead of predictable paths, applying mktemp and cleanup traps consistently across multiple tools.

Changes

Cohort / File(s) Summary
Security Documentation
.jules/sentinel.md
New entry documenting symlink attack and file-overwrite vulnerabilities in shell scripts that download to fixed paths, with prevention approach using secure isolated temporary directories.
Installer Script Hardening
tools/os_installers/apt.sh
Implemented secure temporary directory (TMP_DIR=$(mktemp -d)) with exit trap cleanup. Redirected downloads for Go, yq, lsd, and Composer to TMP_DIR instead of current directory or /tmp/. Updated Composer checksum verification to reference TMP_DIR-scoped installer path.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 Downloads no longer wander wild and free,
In /tmp/ shadows where symlinks play tricks on thee,
Now mktemp keeps them safe in their own little space,
With cleanup traps standing guard at the race—
Security strengthened, one script at a time! 🔒✨

🚥 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 clearly describes the main security fix: addressing a local privilege escalation/symlink vulnerability in apt.sh using secure temporary directories, which aligns with the primary changes made.
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-temp-downloads-2822382016456990647

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: 1

🧹 Nitpick comments (1)
tools/os_installers/apt.sh (1)

212-215: Downloads now staged in secure temp directory.

The security fix is correct. Note that the explicit rm on line 215 is technically redundant since the EXIT trap will clean up $TMP_DIR entirely. The same applies to lines 249, 265, and 268. This "belt-and-suspenders" approach is harmless and can be left as-is for explicit cleanup, or simplified by removing the individual rm calls.

♻️ Optional: Remove redundant cleanup calls
     wget "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" -O "$TMP_DIR/go${GO_VERSION}.linux-amd64.tar.gz"
     sudo rm -rf /usr/local/go
     sudo tar -C /usr/local -xzf "$TMP_DIR/go${GO_VERSION}.linux-amd64.tar.gz"
-    rm "$TMP_DIR/go${GO_VERSION}.linux-amd64.tar.gz"
     echo "NOTE: Add 'export PATH=\$PATH:/usr/local/go/bin' to your shell profile"
 fi

Similar changes can be applied for lsd (line 249) and composer (lines 265, 268).

🤖 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 212 - 215, The explicit per-download
rm calls (e.g., removing "$TMP_DIR/go${GO_VERSION}.linux-amd64.tar.gz" after the
wget/tar sequence that uses TMP_DIR) are redundant because the EXIT trap already
cleans up $TMP_DIR; either remove those individual rm lines (the rm after the go
tarball and the similar rm calls for lsd and composer) to simplify the script,
or keep them if you prefer explicit inline cleanup—locate the wget/tar/rm
sequences that reference "$TMP_DIR" (e.g., the go download block using
GO_VERSION and "$TMP_DIR/go${GO_VERSION}.linux-amd64.tar.gz" and the
lsd/composer download blocks) and delete the standalone rm commands there.
🤖 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: Add a top-level heading at the top of the file by turning the
existing heading "2024-05-18 - [Secure Temp Downloads in Setup Scripts]" into a
H1 (prefix it accordingly), insert a blank line immediately after that H1, and
reflow lines 2–4 so no line exceeds 80 characters (break long sentences and keep
command examples as fenced code blocks or indented code blocks) to satisfy
MD041, MD022 and MD013 lint rules; ensure any inline commands or paths remain
properly escaped/monospaced in the markdown.

---

Nitpick comments:
In `@tools/os_installers/apt.sh`:
- Around line 212-215: The explicit per-download rm calls (e.g., removing
"$TMP_DIR/go${GO_VERSION}.linux-amd64.tar.gz" after the wget/tar sequence that
uses TMP_DIR) are redundant because the EXIT trap already cleans up $TMP_DIR;
either remove those individual rm lines (the rm after the go tarball and the
similar rm calls for lsd and composer) to simplify the script, or keep them if
you prefer explicit inline cleanup—locate the wget/tar/rm sequences that
reference "$TMP_DIR" (e.g., the go download block using GO_VERSION and
"$TMP_DIR/go${GO_VERSION}.linux-amd64.tar.gz" and the lsd/composer download
blocks) and delete the standalone rm commands there.
🪄 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: f793e4bd-d2a4-4786-9ade-f2bc755410c4

📥 Commits

Reviewing files that changed from the base of the PR and between eb5ca40 and 4e331bb.

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

Comment on lines +1 to +4
## 2024-05-18 - [Secure Temp Downloads in Setup Scripts]
**Vulnerability:** Shell scripts downloading binaries directly to the current working directory (`wget ... -O file`) or predictable locations like `/tmp/yq` instead of secure temporary directories.
**Learning:** This is a recurring pattern in OS installer scripts (`apt.sh`) that exposes users to symlink attacks or overwriting unintended files, especially dangerous when using `sudo mv` afterwards.
**Prevention:** Always use securely generated isolated temporary directories for script downloads: `TMP_DIR=$(mktemp -d)` paired with `trap 'rm -rf "$TMP_DIR"' EXIT`. Never hardcode `/tmp/` paths or download indiscriminately to the current working directory.
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 documentation content is accurate, but CI is failing due to markdown lint violations:

  1. MD041: File should start with a top-level heading (#)
  2. MD022: Heading needs a blank line after it
  3. MD013: Lines 2-4 exceed 80 characters
📝 Proposed fix for lint compliance
+# Security Learnings
+
 ## 2024-05-18 - [Secure Temp Downloads in Setup Scripts]
-**Vulnerability:** Shell scripts downloading binaries directly to the current working directory (`wget ... -O file`) or predictable locations like `/tmp/yq` instead of secure temporary directories.
-**Learning:** This is a recurring pattern in OS installer scripts (`apt.sh`) that exposes users to symlink attacks or overwriting unintended files, especially dangerous when using `sudo mv` afterwards.
-**Prevention:** Always use securely generated isolated temporary directories for script downloads: `TMP_DIR=$(mktemp -d)` paired with `trap 'rm -rf "$TMP_DIR"' EXIT`. Never hardcode `/tmp/` paths or download indiscriminately to the current working directory.
+
+**Vulnerability:** Shell scripts downloading binaries directly to the current
+working directory (`wget ... -O file`) or predictable locations like `/tmp/yq`
+instead of secure temporary directories.
+
+**Learning:** This is a recurring pattern in OS installer scripts (`apt.sh`)
+that exposes users to symlink attacks or overwriting unintended files,
+especially dangerous when using `sudo mv` afterward.
+
+**Prevention:** Always use securely generated isolated temporary directories
+for script downloads: `TMP_DIR=$(mktemp -d)` paired with
+`trap 'rm -rf "$TMP_DIR"' EXIT`. Never hardcode `/tmp/` paths or download
+indiscriminately to the current working directory.
📝 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-18 - [Secure Temp Downloads in Setup Scripts]
**Vulnerability:** Shell scripts downloading binaries directly to the current working directory (`wget ... -O file`) or predictable locations like `/tmp/yq` instead of secure temporary directories.
**Learning:** This is a recurring pattern in OS installer scripts (`apt.sh`) that exposes users to symlink attacks or overwriting unintended files, especially dangerous when using `sudo mv` afterwards.
**Prevention:** Always use securely generated isolated temporary directories for script downloads: `TMP_DIR=$(mktemp -d)` paired with `trap 'rm -rf "$TMP_DIR"' EXIT`. Never hardcode `/tmp/` paths or download indiscriminately to the current working directory.
# Security Learnings
## 2024-05-18 - [Secure Temp Downloads in Setup Scripts]
**Vulnerability:** Shell scripts downloading binaries directly to the current
working directory (`wget ... -O file`) or predictable locations like `/tmp/yq`
instead of secure temporary directories.
**Learning:** This is a recurring pattern in OS installer scripts (`apt.sh`)
that exposes users to symlink attacks or overwriting unintended files,
especially dangerous when using `sudo mv` afterward.
**Prevention:** Always use securely generated isolated temporary directories
for script downloads: `TMP_DIR=$(mktemp -d)` paired with
`trap 'rm -rf "$TMP_DIR"' EXIT`. Never hardcode `/tmp/` paths or download
indiscriminately to the current working directory.
🧰 Tools
🪛 GitHub Check: Lint Documentation

[failure] 4-4: Line length
.jules/sentinel.md:4:81 MD013/line-length Line length [Expected: 80; Actual: 258] 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: 201] 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: 197] 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-18 - [Secure Temp D..."] 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-18 - [Secure Temp Downloads in Setup Scripts]"] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md

🪛 LanguageTool

[locale-violation] ~3-~3: In American English, ‘afterward’ is the preferred variant. ‘Afterwards’ is more commonly used in British English and other dialects.
Context: ...pecially dangerous when using sudo mv afterwards. Prevention: Always use securely ge...

(AFTERWARDS_US)

🤖 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, Add a top-level heading at the top of
the file by turning the existing heading "2024-05-18 - [Secure Temp Downloads in
Setup Scripts]" into a H1 (prefix it accordingly), insert a blank line
immediately after that H1, and reflow lines 2–4 so no line exceeds 80 characters
(break long sentences and keep command examples as fenced code blocks or
indented code blocks) to satisfy MD041, MD022 and MD013 lint rules; ensure any
inline commands or paths remain properly escaped/monospaced in the markdown.

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