-
Notifications
You must be signed in to change notification settings - Fork 1
π‘οΈ Sentinel: [CRITICAL] Fix predictable temporary file vulnerability in apt.sh #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -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 | ||||||||||||||||||||||||
|
Comment on lines
+276
to
+280
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§© Analysis chainπ Script executed: #!/bin/bash
# Verify mismatch branch currently does not return non-zero
nl -ba tools/os_installers/apt.sh | sed -n '268,282p'Repository: kidchenko/dotfiles Length of output: 102 π Script executed: cat -n tools/os_installers/apt.sh | sed -n '268,282p'Repository: kidchenko/dotfiles Length of output: 809 π Script executed: cat -n tools/os_installers/apt.sh | sed -n '260,290p'Repository: kidchenko/dotfiles Length of output: 1249 Exit the subshell when Composer checksum validation fails. When the checksum validation fails at line 279, the subshell continues and exits successfully, allowing the script to proceed normally. On integrity failure, the subshell should exit with a non-zero code to prevent the installation from being treated as successful. π‘ Proposed fix 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'
+ exit 1
fiπ Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # Clean up | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π§© Analysis chain
π Script executed:
Repository: kidchenko/dotfiles
Length of output: 1817
Add cryptographic verification before privileged installs.
GO, YQ, and LSD installations (lines 212β214, 242β244, 256β257) download release artifacts and install them with
sudowithout checksum or signature validation. The Terraform installation pattern (line 222) shows how GPG verification can be used; apply similar verification to these three tools.π€ Prompt for AI Agents