From 2f9a86313c6ab75a3efd56470c340f52fed912eb Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 04:58:28 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Fix=20local=20privilege=20escalation=20vulnerability=20in=20?= =?UTF-8?q?apt.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced unsafe downloads to predictable /tmp paths and current directory with secure mktemp -d subshells. 🚨 Severity: CRITICAL 💡 Vulnerability: Installation scripts (apt.sh) downloaded executable artifacts to predictable locations (e.g., /tmp/yq) and current working directory. 🎯 Impact: Predictable /tmp paths introduce symlink attack vulnerabilities and local privilege escalation when run via sudo. Downloads to CWD risk overwriting local files or executing unverified binaries. 🔧 Fix: Updated the go, yq, lsd, and composer downloads to use a dynamically generated, isolated directory created with `mktemp -d`, wrapped securely within a subshell with a cleanup trap (`trap 'rm -rf "$TMP_DIR"' EXIT`). ✅ Verification: `./build.sh` executed successfully ensuring no regressions. Reading `apt.sh` confirms the subshells correctly isolate the new download logic. Co-authored-by: kidchenko <5432753+kidchenko@users.noreply.github.com> --- .jules/sentinel.md | 4 +++ tools/os_installers/apt.sh | 64 ++++++++++++++++++++++++-------------- 2 files changed, 44 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..45d07a4 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-04-06 - Unsafe File Downloads in Installation Scripts +**Vulnerability:** Installation scripts (`apt.sh`) were downloading executable artifacts directly to predictable locations (`/tmp/yq`) and the current working directory, risking symlink attacks, local privilege escalation, and overwriting existing files. +**Learning:** Shell scripts running with elevated privileges must never use hardcoded or predictable paths for temporary files, and downloading files to the current working directory is dangerous when executing as root or in unknown environments. +**Prevention:** Always use secure, randomly generated temporary directories via `mktemp -d` for downloading and processing installation artifacts. Wrap the logic in a subshell `(...)` and pair it with a local trap (e.g., `trap 'rm -rf "$TMP_DIR"' EXIT`) to ensure automatic cleanup upon exit. diff --git a/tools/os_installers/apt.sh b/tools/os_installers/apt.sh index 156016b..c4f17e2 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