From bea60251c5003d48c9841dff30d9bfe20dcf7bb0 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 04:49:09 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Fix=20predictable=20temporary=20file=20vulnerability=20in=20?= =?UTF-8?q?apt.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🚨 Severity: CRITICAL 💡 Vulnerability: Predictable temporary file path and unsafe working directory downloading allows for symlink attacks and race conditions when downloading system binaries. 🎯 Impact: Attackers could potentially overwrite system binaries before they get moved with `sudo` during the installation, leading to local privilege escalation. 🔧 Fix: Wrapped download and extraction steps inside a subshell using securely created `TMP_DIR=$(mktemp -d)` and a local `trap` for guaranteed cleanup. ✅ Verification: Ran syntax checking and `./build.sh` suite to verify tests pass and no shellcheck errors are introduced. Verified `.jules/sentinel.md` learnings were recorded appropriately. Co-authored-by: kidchenko <5432753+kidchenko@users.noreply.github.com> --- .jules/sentinel.md | 18 +++++++++++ tools/os_installers/apt.sh | 64 ++++++++++++++++++++++++-------------- 2 files changed, 58 insertions(+), 24 deletions(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..8f4cdd8 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,18 @@ +# Sentinel Journal + +## 2023-10-25 - Predictable temporary file path vulnerability in installer + +**Vulnerability:** Installation scripts downloaded files directly to the current +working directory or to predictable temporary file locations (e.g. `/tmp/yq`), +which could allow an attacker to predict and poison files or leverage symlink +attacks. +**Learning:** These paths create a Time-of-Check to Time-of-Use (TOCTOU) +vulnerability where an attacker can replace a downloaded binary with a malicious +one before it is executed or moved by an administrative command (`sudo`). Using +the current working directory is risky since its permissions are not strictly +isolated and could cause accidental overwrites. +**Prevention:** Always use dynamically and securely created temporary +directories generated with `mktemp -d` for installation operations. Wrap the +download and extraction commands inside a subshell `(...)` and assign a local +trap (e.g., `trap 'rm -rf "$TMP_DIR"' EXIT`) to guarantee proper cleanup +independently. diff --git a/tools/os_installers/apt.sh b/tools/os_installers/apt.sh index 156016b..fae496e 100644 --- a/tools/os_installers/apt.sh +++ b/tools/os_installers/apt.sh @@ -204,11 +204,15 @@ fi # Install Go echo "Installing Go..." if ! command -v go &> /dev/null; then - GO_VERSION="1.23.4" - wget "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" - sudo rm -rf /usr/local/go - sudo tar -C /usr/local -xzf "go${GO_VERSION}.linux-amd64.tar.gz" - rm "go${GO_VERSION}.linux-amd64.tar.gz" + ( + TMP_DIR=$(mktemp -d) + trap 'rm -rf "$TMP_DIR"' EXIT + cd "$TMP_DIR" || exit 1 + GO_VERSION="1.23.4" + wget "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" + sudo rm -rf /usr/local/go + sudo tar -C /usr/local -xzf "go${GO_VERSION}.linux-amd64.tar.gz" + ) echo "NOTE: Add 'export PATH=\$PATH:/usr/local/go/bin' to your shell profile" fi @@ -230,19 +234,28 @@ fi # Install yq echo "Installing yq..." if ! command -v yq &> /dev/null; then - YQ_VERSION="v4.44.6" - wget "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64" -O /tmp/yq - sudo mv /tmp/yq /usr/local/bin/yq - sudo chmod +x /usr/local/bin/yq + ( + TMP_DIR=$(mktemp -d) + trap 'rm -rf "$TMP_DIR"' EXIT + cd "$TMP_DIR" || exit 1 + YQ_VERSION="v4.44.6" + wget "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64" -O yq + sudo mv yq /usr/local/bin/yq + sudo chmod +x /usr/local/bin/yq + ) fi # Install lsd (LSDeluxe) echo "Installing lsd..." if ! command -v lsd &> /dev/null; then - LSD_VERSION="1.1.5" - wget "https://github.com/lsd-rs/lsd/releases/download/v${LSD_VERSION}/lsd_${LSD_VERSION}_amd64.deb" - sudo dpkg -i "lsd_${LSD_VERSION}_amd64.deb" - rm "lsd_${LSD_VERSION}_amd64.deb" + ( + TMP_DIR=$(mktemp -d) + trap 'rm -rf "$TMP_DIR"' EXIT + cd "$TMP_DIR" || exit 1 + LSD_VERSION="1.1.5" + wget "https://github.com/lsd-rs/lsd/releases/download/v${LSD_VERSION}/lsd_${LSD_VERSION}_amd64.deb" + sudo dpkg -i "lsd_${LSD_VERSION}_amd64.deb" + ) fi # Install Tesseract OCR @@ -252,17 +265,20 @@ sudo apt install -y tesseract-ocr # Install PHP Composer echo "Installing Composer..." if ! command -v composer &> /dev/null; then - EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')" - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" - ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" - - if [ "$EXPECTED_CHECKSUM" = "$ACTUAL_CHECKSUM" ]; then - sudo php composer-setup.php --quiet --install-dir=/usr/local/bin --filename=composer - rm composer-setup.php - else - >&2 echo 'ERROR: Invalid installer checksum for Composer' - rm composer-setup.php - fi + ( + TMP_DIR=$(mktemp -d) + trap 'rm -rf "$TMP_DIR"' EXIT + cd "$TMP_DIR" || exit 1 + EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')" + php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" + ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" + + if [ "$EXPECTED_CHECKSUM" = "$ACTUAL_CHECKSUM" ]; then + sudo php composer-setup.php --quiet --install-dir=/usr/local/bin --filename=composer + else + >&2 echo 'ERROR: Invalid installer checksum for Composer' + fi + ) fi # Clean up