From 3820dd55a0236a3ad8a9d6c5a04cb944e91b1014 Mon Sep 17 00:00:00 2001 From: urugus <21075381+urugus@users.noreply.github.com> Date: Wed, 1 Apr 2026 22:03:21 +0900 Subject: [PATCH 1/3] security: harden supply chain dependencies --- .config/nvim/lua/rc/plugins/init.lua | 7 +++- .config/zsh/rc/pluginlist.zsh | 10 ++++- .github/workflows/gitguardian.yml | 5 ++- .github/workflows/lua-lint.yml | 12 +++++- .github/workflows/neovim-health.yml | 7 ++-- .../lib/dotinstaller/install-brewfile.sh | 21 +++++++++- .../lib/dotinstaller/install-fonts.sh | 42 ++++++++++++++----- .../lib/dotinstaller/install-homebrew.sh | 24 ++++++++++- .../lib/dotinstaller/install-skk.sh | 3 +- 9 files changed, 107 insertions(+), 24 deletions(-) diff --git a/.config/nvim/lua/rc/plugins/init.lua b/.config/nvim/lua/rc/plugins/init.lua index 77abc54..eb8c236 100644 --- a/.config/nvim/lua/rc/plugins/init.lua +++ b/.config/nvim/lua/rc/plugins/init.lua @@ -1,7 +1,12 @@ local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if not (vim.uv or vim.loop).fs_stat(lazypath) then local lazyrepo = "https://github.com/folke/lazy.nvim.git" - local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) + -- Supply-chain hardening: pin to a specific commit instead of --branch=stable + -- Commit from lazy-lock.json; update both when upgrading lazy.nvim + local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--single-branch", lazyrepo, lazypath }) + if vim.v.shell_error == 0 then + vim.fn.system({ "git", "-C", lazypath, "checkout", "306a05526ada86a7b30af95c5cc81ffba93fef97" }) + end if vim.v.shell_error ~= 0 then vim.api.nvim_echo({ { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, diff --git a/.config/zsh/rc/pluginlist.zsh b/.config/zsh/rc/pluginlist.zsh index cd939b9..3eaad28 100644 --- a/.config/zsh/rc/pluginlist.zsh +++ b/.config/zsh/rc/pluginlist.zsh @@ -7,7 +7,8 @@ fi if ! test -d "$ZPLG_HOME"; then mkdir -p "$ZPLG_HOME" chmod g-rwX "$ZPLG_HOME" - git clone --depth 10 https://github.com/zdharma-continuum/zinit.git ${ZPLG_HOME}/bin + # Supply-chain hardening: pin zinit to a specific commit + git clone --depth 10 --branch v3.14.0 https://github.com/zdharma-continuum/zinit.git ${ZPLG_HOME}/bin fi typeset -gAH ZPLGM ZPLGM[HOME_DIR]="${ZPLG_HOME}" @@ -23,16 +24,20 @@ autoload -Uz _zinit #--------------------------------# # history #--------------------------------# +# Supply-chain hardening: pin each plugin to a specific commit via ver"" zinit wait'1' lucid \ if"(( ${ZSH_VERSION%%.*} > 4.4))" \ + ver"14c8d2e0ffaee98f2df9850b19944f32546fdea5" \ light-mode for @zsh-users/zsh-history-substring-search zinit wait'1' lucid \ if"(( ${ZSH_VERSION%%.*} > 4.4))" \ + ver"9bc52fed2900460fc4bef0a77c9382d6175eb63a" \ light-mode for @zdharma/history-search-multi-word zinit wait'1' lucid \ if"(( ${ZSH_VERSION%%.*} > 4.4))" \ + ver"598675303044df8e9d04722f3adff4f63a238922" \ light-mode for @mollifier/anyframe autoload -Uz chpwd_recent_dirs cdr add-zsh-hook add-zsh-hook chpwd chpwd_recent_dirs @@ -54,10 +59,12 @@ zinit wait'1' lucid \ #--------------------------------# zinit wait'0' lucid \ if"(( ${ZSH_VERSION%%.*} > 4.4))" \ + ver"85919cd1ffa7d2d5412f6d3fe437ebdbeeec4fc5" \ light-mode for @zsh-users/zsh-autosuggestions zinit wait'1' lucid \ if"(( ${ZSH_VERSION%%.*} > 4.4))" \ + ver"adad765241061b9b63485991f268b2771524ed42" \ light-mode for @zsh-users/zsh-completions #--------------------------------# @@ -65,6 +72,7 @@ zinit wait'1' lucid \ # --------------------------------# zinit wait'1' lucid \ if"(( ${ZSH_VERSION%%.*} > 4.4))" \ + ver"1d85c692615a25fe2293bdd44b34c217d5d2bf04" \ light-mode for @zsh-users/zsh-syntax-highlighting #--------------------------------# diff --git a/.github/workflows/gitguardian.yml b/.github/workflows/gitguardian.yml index dda6da5..a6b6d49 100644 --- a/.github/workflows/gitguardian.yml +++ b/.github/workflows/gitguardian.yml @@ -8,11 +8,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + # Supply-chain hardening: pin actions to full commit SHA + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 0 # fetch all history so multiple commits can be scanned - name: GitGuardian scan - uses: GitGuardian/ggshield-action@v1 + uses: GitGuardian/ggshield-action@8fc5e12b83a2f2a9f71b88bb12d0d5cf152b1689 # v1.49.0 env: GITHUB_PUSH_BEFORE_SHA: ${{ github.event.before }} GITHUB_PUSH_BASE_SHA: ${{ github.event.base }} diff --git a/.github/workflows/lua-lint.yml b/.github/workflows/lua-lint.yml index 506db67..fb1f247 100644 --- a/.github/workflows/lua-lint.yml +++ b/.github/workflows/lua-lint.yml @@ -14,11 +14,12 @@ jobs: env: CI: true steps: - - uses: actions/checkout@v4 + # Supply-chain hardening: pin actions to full commit SHA + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Cache lint tools id: cache-tools - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: ~/.local/bin key: lint-tools-stylua-0.20.0-selene-0.27.1 @@ -27,11 +28,18 @@ jobs: if: steps.cache-tools.outputs.cache-hit != 'true' run: | mkdir -p ~/.local/bin + + # Supply-chain hardening: verify checksums of downloaded binaries + STYLUA_SHA256="28eddb9257bf85b20b1c337e536b7a3d16ba308863f067d447c1f4d24c6dec64" curl -LO https://github.com/JohnnyMorganz/StyLua/releases/download/v0.20.0/stylua-linux-x86_64.zip + echo "${STYLUA_SHA256} stylua-linux-x86_64.zip" | sha256sum -c - unzip stylua-linux-x86_64.zip -d ~/.local/bin chmod +x ~/.local/bin/stylua rm stylua-linux-x86_64.zip + + SELENE_SHA256="22dabfe070c6d10cbb0b8ae56a82abfa131fbb902bff03d9924f0f73fd3d3318" curl -LO https://github.com/Kampfkarren/selene/releases/download/0.27.1/selene-0.27.1-linux.zip + echo "${SELENE_SHA256} selene-0.27.1-linux.zip" | sha256sum -c - unzip selene-0.27.1-linux.zip -d ~/.local/bin chmod +x ~/.local/bin/selene rm selene-0.27.1-linux.zip diff --git a/.github/workflows/neovim-health.yml b/.github/workflows/neovim-health.yml index cf6f67a..ac7e3b9 100644 --- a/.github/workflows/neovim-health.yml +++ b/.github/workflows/neovim-health.yml @@ -17,16 +17,17 @@ jobs: env: CI: true steps: - - uses: actions/checkout@v4 + # Supply-chain hardening: pin actions to full commit SHA + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Install Neovim - uses: rhysd/action-setup-vim@v1 + uses: rhysd/action-setup-vim@febef33995d6649302e9d88dda81e071b68f16a7 # v1.6.1 with: neovim: true version: ${{ matrix.channel }} - name: Cache lazy.nvim directories - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: | ${{ github.workspace }}/.local/share/nvim diff --git a/install_scripts/lib/dotinstaller/install-brewfile.sh b/install_scripts/lib/dotinstaller/install-brewfile.sh index 2bef9e2..b8e448f 100755 --- a/install_scripts/lib/dotinstaller/install-brewfile.sh +++ b/install_scripts/lib/dotinstaller/install-brewfile.sh @@ -16,8 +16,25 @@ function main() { fi echo "Brewfile is not installed. Installing Brewfile..." - # Brewfileのインストール - curl -o install.sh -fsSL https://raw.github.com/rcmdnk/homebrew-file/install/install.sh + + # Supply-chain hardening: pin to a specific commit on the install branch + local brewfile_commit="723acc6f3e0db4677c03bb87c4ea33157d549e26" + local expected_sha256="464d39329e5e13939861dab96fbaf64e30513ef4a0666b7edaf7784079ba6fa7" + + curl -o install.sh -fsSL \ + "https://raw.githubusercontent.com/rcmdnk/homebrew-file/${brewfile_commit}/install.sh" + + # Verify SHA256 checksum before execution (update hash when bumping commit) + local actual_sha256 + actual_sha256=$(shasum -a 256 install.sh | awk '{print $1}') + if [ "$actual_sha256" != "$expected_sha256" ]; then + echo "🚨ERROR🚨 homebrew-file install script checksum mismatch!" + echo " expected: ${expected_sha256}" + echo " actual: ${actual_sha256}" + rm -f install.sh + exit 1 + fi + chmod 755 ./install.sh ./install.sh rm -f install.sh diff --git a/install_scripts/lib/dotinstaller/install-fonts.sh b/install_scripts/lib/dotinstaller/install-fonts.sh index a15fe90..3da58ea 100755 --- a/install_scripts/lib/dotinstaller/install-fonts.sh +++ b/install_scripts/lib/dotinstaller/install-fonts.sh @@ -2,25 +2,47 @@ set -ue +# Supply-chain hardening: pin font releases and verify checksums +verify_checksum() { + local file="$1" expected="$2" + local actual + actual=$(shasum -a 256 "$file" | awk '{print $1}') + if [ "$actual" != "$expected" ]; then + echo "🚨ERROR🚨 Checksum mismatch for ${file}!" + echo " expected: ${expected}" + echo " actual: ${actual}" + rm -f "$file" + exit 1 + fi +} + mkdir -p ~/.local/share/fonts -# udev gothic +# udev gothic — pinned to v2.2.0 +UDEV_GOTHIC_VERSION="v2.2.0" +UDEV_GOTHIC_SHA256="c104c171f6ed8922ca52d74cd915a271e427f1e884e51431aae71d99e8b3b47b" mkdir -p ~/.local/share/fonts/UDEVGothic -UDEV_GOTHIC_RELEASES_URL="https://api.github.com/repos/yuru7/udev-gothic/releases" -curl -sfL "${UDEV_GOTHIC_RELEASES_URL}" | jq -r '.[0].assets | .[].browser_download_url' | xargs -I{} curl -fL -o /tmp/UDEVGothic.zip "{}" +curl -fL -o /tmp/UDEVGothic.zip \ + "https://github.com/yuru7/udev-gothic/releases/download/${UDEV_GOTHIC_VERSION}/UDEVGothic_${UDEV_GOTHIC_VERSION}.zip" +verify_checksum /tmp/UDEVGothic.zip "$UDEV_GOTHIC_SHA256" (cd /tmp && unzip -j -o UDEVGothic.zip -d ~/.local/share/fonts/UDEVGothic) -# Hack Nerd Font +# Hack Nerd Font — pinned to v3.4.0 +HACK_NERD_FONT_VERSION="v3.4.0" +HACK_NERD_FONT_SHA256="8ca33a60c791392d872b80d26c42f2bfa914a480f9eb2d7516d9f84373c36897" mkdir -p ~/.local/share/fonts/HackNerdFont -HACK_NERD_FONT_RELEASES_URL="https://api.github.com/repos/ryanoasis/nerd-fonts/releases" -curl -sfL "${HACK_NERD_FONT_RELEASES_URL}" | jq -r '.[0].assets | .[].browser_download_url' | grep Hack.zip | xargs -I{} curl -fL -o /tmp/HackNerdFont.zip "{}" +curl -fL -o /tmp/HackNerdFont.zip \ + "https://github.com/ryanoasis/nerd-fonts/releases/download/${HACK_NERD_FONT_VERSION}/Hack.zip" +verify_checksum /tmp/HackNerdFont.zip "$HACK_NERD_FONT_SHA256" (cd /tmp && unzip -j -o HackNerdFont.zip -d ~/.local/share/fonts/HackNerdFont) -# Fira Code +# Fira Code — pinned to 6.2 +FIRA_CODE_VERSION="6.2" +FIRA_CODE_SHA256="0949915ba8eb24d89fd93d10a7ff623f42830d7c5ffc3ecbf960e4ecad3e3e79" mkdir -p ~/.local/share/fonts/FiraCode -FIRA_CODE_RELEASES_URL="https://api.github.com/repos/tonsky/FiraCode/releases" -LATEST_ZIP_URL=$(curl -sfL "${FIRA_CODE_RELEASES_URL}" | jq -r '.[0].assets[] | select(.name | contains(".zip")) | .browser_download_url') -curl -fL -o /tmp/FiraCode.zip "${LATEST_ZIP_URL}" +curl -fL -o /tmp/FiraCode.zip \ + "https://github.com/tonsky/FiraCode/releases/download/${FIRA_CODE_VERSION}/Fira_Code_v${FIRA_CODE_VERSION}.zip" +verify_checksum /tmp/FiraCode.zip "$FIRA_CODE_SHA256" (cd /tmp && unzip -j -o FiraCode.zip -d ~/.local/share/fonts/FiraCode) fc-cache -vf diff --git a/install_scripts/lib/dotinstaller/install-homebrew.sh b/install_scripts/lib/dotinstaller/install-homebrew.sh index b2bd0fc..859cffd 100755 --- a/install_scripts/lib/dotinstaller/install-homebrew.sh +++ b/install_scripts/lib/dotinstaller/install-homebrew.sh @@ -16,8 +16,28 @@ function main() { fi echo "Homebrew is not installed. Installing Homebrew..." - # Homebrewのインストール - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + + # Supply-chain hardening: pin to a specific commit instead of HEAD + local brew_commit="6d5e2670d07961e7985d2079a2f0a484420f3c38" + local brew_script="/tmp/homebrew-install.sh" + local expected_sha256="dfd5145fe2aa5956a600e35848765273f5798ce6def01bd08ecec088a1268d91" + + curl -fsSL "https://raw.githubusercontent.com/Homebrew/install/${brew_commit}/install.sh" \ + -o "$brew_script" + + # Verify SHA256 checksum before execution (update hash when bumping brew_commit) + local actual_sha256 + actual_sha256=$(shasum -a 256 "$brew_script" | awk '{print $1}') + if [ "$actual_sha256" != "$expected_sha256" ]; then + echo "🚨ERROR🚨 Homebrew install script checksum mismatch!" + echo " expected: ${expected_sha256}" + echo " actual: ${actual_sha256}" + rm -f "$brew_script" + exit 1 + fi + + /bin/bash "$brew_script" + rm -f "$brew_script" # インストールが成功したか再確認 if is_homebrew_installed; then diff --git a/install_scripts/lib/dotinstaller/install-skk.sh b/install_scripts/lib/dotinstaller/install-skk.sh index 586ecc2..d640f49 100755 --- a/install_scripts/lib/dotinstaller/install-skk.sh +++ b/install_scripts/lib/dotinstaller/install-skk.sh @@ -1,8 +1,9 @@ #!/bin/bash # install yaskkserv2 +# Supply-chain hardening: pin to a specific release tag if ! command -v yaskkserv2 >/dev/temp/null; then - cargo install --git https://github.com/wachikun/yaskkserv2 --locked --bins + cargo install --git https://github.com/wachikun/yaskkserv2 --tag 0.1.7 --locked --bins fi # setup launch agent From 0c5cb6c41f1e1d0baaa8b85f5fd13efd966dfcb4 Mon Sep 17 00:00:00 2001 From: urugus <21075381+urugus@users.noreply.github.com> Date: Wed, 1 Apr 2026 23:13:12 +0900 Subject: [PATCH 2/3] security: address review feedback on supply chain hardening - Fix /dev/temp/null typo to /dev/null in install-skk.sh - Use mktemp + trap for temp files instead of fixed /tmp paths - Add sha256sum/shasum fallback for Linux compatibility - Fix zinit comment to reflect tag pinning (not commit pinning) - Quote ZPLG_HOME path in zinit clone --- .config/zsh/rc/pluginlist.zsh | 4 +-- .../lib/dotinstaller/install-brewfile.sh | 21 +++++++++---- .../lib/dotinstaller/install-fonts.sh | 31 +++++++++++++------ .../lib/dotinstaller/install-homebrew.sh | 16 +++++++--- .../lib/dotinstaller/install-skk.sh | 2 +- 5 files changed, 51 insertions(+), 23 deletions(-) diff --git a/.config/zsh/rc/pluginlist.zsh b/.config/zsh/rc/pluginlist.zsh index 3eaad28..92e7376 100644 --- a/.config/zsh/rc/pluginlist.zsh +++ b/.config/zsh/rc/pluginlist.zsh @@ -7,8 +7,8 @@ fi if ! test -d "$ZPLG_HOME"; then mkdir -p "$ZPLG_HOME" chmod g-rwX "$ZPLG_HOME" - # Supply-chain hardening: pin zinit to a specific commit - git clone --depth 10 --branch v3.14.0 https://github.com/zdharma-continuum/zinit.git ${ZPLG_HOME}/bin + # Supply-chain hardening: pin zinit to tag v3.14.0 + git clone --depth 10 --branch v3.14.0 https://github.com/zdharma-continuum/zinit.git "${ZPLG_HOME}/bin" fi typeset -gAH ZPLGM ZPLGM[HOME_DIR]="${ZPLG_HOME}" diff --git a/install_scripts/lib/dotinstaller/install-brewfile.sh b/install_scripts/lib/dotinstaller/install-brewfile.sh index b8e448f..5c111df 100755 --- a/install_scripts/lib/dotinstaller/install-brewfile.sh +++ b/install_scripts/lib/dotinstaller/install-brewfile.sh @@ -6,6 +6,14 @@ function is_brewfile_installed() { command -v brew-file >/dev/null 2>&1 } +_sha256() { + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$1" | awk '{print $1}' + else + shasum -a 256 "$1" | awk '{print $1}' + fi +} + function main() { local current_dir current_dir=$(dirname "${BASH_SOURCE[0]:-$0}") @@ -20,24 +28,25 @@ function main() { # Supply-chain hardening: pin to a specific commit on the install branch local brewfile_commit="723acc6f3e0db4677c03bb87c4ea33157d549e26" local expected_sha256="464d39329e5e13939861dab96fbaf64e30513ef4a0666b7edaf7784079ba6fa7" + local install_script + install_script=$(mktemp) + trap 'rm -f "$install_script"' EXIT - curl -o install.sh -fsSL \ + curl -fsSL -o "$install_script" \ "https://raw.githubusercontent.com/rcmdnk/homebrew-file/${brewfile_commit}/install.sh" # Verify SHA256 checksum before execution (update hash when bumping commit) local actual_sha256 - actual_sha256=$(shasum -a 256 install.sh | awk '{print $1}') + actual_sha256=$(_sha256 "$install_script") if [ "$actual_sha256" != "$expected_sha256" ]; then echo "🚨ERROR🚨 homebrew-file install script checksum mismatch!" echo " expected: ${expected_sha256}" echo " actual: ${actual_sha256}" - rm -f install.sh exit 1 fi - chmod 755 ./install.sh - ./install.sh - rm -f install.sh + chmod 755 "$install_script" + "$install_script" # インストールが成功したか再確認 if is_brewfile_installed; then diff --git a/install_scripts/lib/dotinstaller/install-fonts.sh b/install_scripts/lib/dotinstaller/install-fonts.sh index 3da58ea..5c2dd03 100755 --- a/install_scripts/lib/dotinstaller/install-fonts.sh +++ b/install_scripts/lib/dotinstaller/install-fonts.sh @@ -3,10 +3,18 @@ set -ue # Supply-chain hardening: pin font releases and verify checksums +_sha256() { + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$1" | awk '{print $1}' + else + shasum -a 256 "$1" | awk '{print $1}' + fi +} + verify_checksum() { local file="$1" expected="$2" local actual - actual=$(shasum -a 256 "$file" | awk '{print $1}') + actual=$(_sha256 "$file") if [ "$actual" != "$expected" ]; then echo "🚨ERROR🚨 Checksum mismatch for ${file}!" echo " expected: ${expected}" @@ -16,33 +24,36 @@ verify_checksum() { fi } +FONT_TMPDIR=$(mktemp -d) +trap 'rm -rf "$FONT_TMPDIR"' EXIT + mkdir -p ~/.local/share/fonts # udev gothic — pinned to v2.2.0 UDEV_GOTHIC_VERSION="v2.2.0" UDEV_GOTHIC_SHA256="c104c171f6ed8922ca52d74cd915a271e427f1e884e51431aae71d99e8b3b47b" mkdir -p ~/.local/share/fonts/UDEVGothic -curl -fL -o /tmp/UDEVGothic.zip \ +curl -fL -o "$FONT_TMPDIR/UDEVGothic.zip" \ "https://github.com/yuru7/udev-gothic/releases/download/${UDEV_GOTHIC_VERSION}/UDEVGothic_${UDEV_GOTHIC_VERSION}.zip" -verify_checksum /tmp/UDEVGothic.zip "$UDEV_GOTHIC_SHA256" -(cd /tmp && unzip -j -o UDEVGothic.zip -d ~/.local/share/fonts/UDEVGothic) +verify_checksum "$FONT_TMPDIR/UDEVGothic.zip" "$UDEV_GOTHIC_SHA256" +(cd "$FONT_TMPDIR" && unzip -j -o UDEVGothic.zip -d ~/.local/share/fonts/UDEVGothic) # Hack Nerd Font — pinned to v3.4.0 HACK_NERD_FONT_VERSION="v3.4.0" HACK_NERD_FONT_SHA256="8ca33a60c791392d872b80d26c42f2bfa914a480f9eb2d7516d9f84373c36897" mkdir -p ~/.local/share/fonts/HackNerdFont -curl -fL -o /tmp/HackNerdFont.zip \ +curl -fL -o "$FONT_TMPDIR/HackNerdFont.zip" \ "https://github.com/ryanoasis/nerd-fonts/releases/download/${HACK_NERD_FONT_VERSION}/Hack.zip" -verify_checksum /tmp/HackNerdFont.zip "$HACK_NERD_FONT_SHA256" -(cd /tmp && unzip -j -o HackNerdFont.zip -d ~/.local/share/fonts/HackNerdFont) +verify_checksum "$FONT_TMPDIR/HackNerdFont.zip" "$HACK_NERD_FONT_SHA256" +(cd "$FONT_TMPDIR" && unzip -j -o HackNerdFont.zip -d ~/.local/share/fonts/HackNerdFont) # Fira Code — pinned to 6.2 FIRA_CODE_VERSION="6.2" FIRA_CODE_SHA256="0949915ba8eb24d89fd93d10a7ff623f42830d7c5ffc3ecbf960e4ecad3e3e79" mkdir -p ~/.local/share/fonts/FiraCode -curl -fL -o /tmp/FiraCode.zip \ +curl -fL -o "$FONT_TMPDIR/FiraCode.zip" \ "https://github.com/tonsky/FiraCode/releases/download/${FIRA_CODE_VERSION}/Fira_Code_v${FIRA_CODE_VERSION}.zip" -verify_checksum /tmp/FiraCode.zip "$FIRA_CODE_SHA256" -(cd /tmp && unzip -j -o FiraCode.zip -d ~/.local/share/fonts/FiraCode) +verify_checksum "$FONT_TMPDIR/FiraCode.zip" "$FIRA_CODE_SHA256" +(cd "$FONT_TMPDIR" && unzip -j -o FiraCode.zip -d ~/.local/share/fonts/FiraCode) fc-cache -vf diff --git a/install_scripts/lib/dotinstaller/install-homebrew.sh b/install_scripts/lib/dotinstaller/install-homebrew.sh index 859cffd..2b8c0e1 100755 --- a/install_scripts/lib/dotinstaller/install-homebrew.sh +++ b/install_scripts/lib/dotinstaller/install-homebrew.sh @@ -6,6 +6,14 @@ function is_homebrew_installed() { command -v brew >/dev/null 2>&1 } +_sha256() { + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$1" | awk '{print $1}' + else + shasum -a 256 "$1" | awk '{print $1}' + fi +} + function main() { local current_dir current_dir=$(dirname "${BASH_SOURCE[0]:-$0}") @@ -19,25 +27,25 @@ function main() { # Supply-chain hardening: pin to a specific commit instead of HEAD local brew_commit="6d5e2670d07961e7985d2079a2f0a484420f3c38" - local brew_script="/tmp/homebrew-install.sh" local expected_sha256="dfd5145fe2aa5956a600e35848765273f5798ce6def01bd08ecec088a1268d91" + local brew_script + brew_script=$(mktemp) + trap 'rm -f "$brew_script"' EXIT curl -fsSL "https://raw.githubusercontent.com/Homebrew/install/${brew_commit}/install.sh" \ -o "$brew_script" # Verify SHA256 checksum before execution (update hash when bumping brew_commit) local actual_sha256 - actual_sha256=$(shasum -a 256 "$brew_script" | awk '{print $1}') + actual_sha256=$(_sha256 "$brew_script") if [ "$actual_sha256" != "$expected_sha256" ]; then echo "🚨ERROR🚨 Homebrew install script checksum mismatch!" echo " expected: ${expected_sha256}" echo " actual: ${actual_sha256}" - rm -f "$brew_script" exit 1 fi /bin/bash "$brew_script" - rm -f "$brew_script" # インストールが成功したか再確認 if is_homebrew_installed; then diff --git a/install_scripts/lib/dotinstaller/install-skk.sh b/install_scripts/lib/dotinstaller/install-skk.sh index d640f49..d5515b2 100755 --- a/install_scripts/lib/dotinstaller/install-skk.sh +++ b/install_scripts/lib/dotinstaller/install-skk.sh @@ -2,7 +2,7 @@ # install yaskkserv2 # Supply-chain hardening: pin to a specific release tag -if ! command -v yaskkserv2 >/dev/temp/null; then +if ! command -v yaskkserv2 >/dev/null 2>&1; then cargo install --git https://github.com/wachikun/yaskkserv2 --tag 0.1.7 --locked --bins fi From e800567b1e3e1ee4df7bdfb286fbc79bd78a1102 Mon Sep 17 00:00:00 2001 From: urugus <21075381+urugus@users.noreply.github.com> Date: Thu, 2 Apr 2026 09:51:32 +0900 Subject: [PATCH 3/3] security: address second round of review feedback - Use portable mktemp templates for macOS BSD compatibility - Pin zinit to commit hash instead of tag (tags can be retargeted) - Improve lazy.nvim bootstrap error reporting for checkout failures --- .config/nvim/lua/rc/plugins/init.lua | 7 +++++-- .config/zsh/rc/pluginlist.zsh | 5 +++-- install_scripts/lib/dotinstaller/install-brewfile.sh | 2 +- install_scripts/lib/dotinstaller/install-fonts.sh | 2 +- install_scripts/lib/dotinstaller/install-homebrew.sh | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.config/nvim/lua/rc/plugins/init.lua b/.config/nvim/lua/rc/plugins/init.lua index eb8c236..22fe5b7 100644 --- a/.config/nvim/lua/rc/plugins/init.lua +++ b/.config/nvim/lua/rc/plugins/init.lua @@ -5,11 +5,14 @@ if not (vim.uv or vim.loop).fs_stat(lazypath) then -- Commit from lazy-lock.json; update both when upgrading lazy.nvim local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--single-branch", lazyrepo, lazypath }) if vim.v.shell_error == 0 then - vim.fn.system({ "git", "-C", lazypath, "checkout", "306a05526ada86a7b30af95c5cc81ffba93fef97" }) + local co_out = vim.fn.system({ "git", "-C", lazypath, "checkout", "306a05526ada86a7b30af95c5cc81ffba93fef97" }) + if vim.v.shell_error ~= 0 then + out = co_out + end end if vim.v.shell_error ~= 0 then vim.api.nvim_echo({ - { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, + { "Failed to install lazy.nvim:\n", "ErrorMsg" }, { out, "WarningMsg" }, { "\nPress any key to exit..." }, }, true, {}) diff --git a/.config/zsh/rc/pluginlist.zsh b/.config/zsh/rc/pluginlist.zsh index 92e7376..7bef88d 100644 --- a/.config/zsh/rc/pluginlist.zsh +++ b/.config/zsh/rc/pluginlist.zsh @@ -7,8 +7,9 @@ fi if ! test -d "$ZPLG_HOME"; then mkdir -p "$ZPLG_HOME" chmod g-rwX "$ZPLG_HOME" - # Supply-chain hardening: pin zinit to tag v3.14.0 - git clone --depth 10 --branch v3.14.0 https://github.com/zdharma-continuum/zinit.git "${ZPLG_HOME}/bin" + # Supply-chain hardening: pin zinit to commit corresponding to v3.14.0 + git clone --depth 1 https://github.com/zdharma-continuum/zinit.git "${ZPLG_HOME}/bin" + (cd "${ZPLG_HOME}/bin" && git checkout --detach 412ff3b6d9c0cd9ceb4b4f17aea39dda9e1abad5) fi typeset -gAH ZPLGM ZPLGM[HOME_DIR]="${ZPLG_HOME}" diff --git a/install_scripts/lib/dotinstaller/install-brewfile.sh b/install_scripts/lib/dotinstaller/install-brewfile.sh index 5c111df..60ce9b5 100755 --- a/install_scripts/lib/dotinstaller/install-brewfile.sh +++ b/install_scripts/lib/dotinstaller/install-brewfile.sh @@ -29,7 +29,7 @@ function main() { local brewfile_commit="723acc6f3e0db4677c03bb87c4ea33157d549e26" local expected_sha256="464d39329e5e13939861dab96fbaf64e30513ef4a0666b7edaf7784079ba6fa7" local install_script - install_script=$(mktemp) + install_script=$(mktemp "${TMPDIR:-/tmp}/brewfile-install.XXXXXX") trap 'rm -f "$install_script"' EXIT curl -fsSL -o "$install_script" \ diff --git a/install_scripts/lib/dotinstaller/install-fonts.sh b/install_scripts/lib/dotinstaller/install-fonts.sh index 5c2dd03..618f123 100755 --- a/install_scripts/lib/dotinstaller/install-fonts.sh +++ b/install_scripts/lib/dotinstaller/install-fonts.sh @@ -24,7 +24,7 @@ verify_checksum() { fi } -FONT_TMPDIR=$(mktemp -d) +FONT_TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/dotinstaller-fonts.XXXXXX") trap 'rm -rf "$FONT_TMPDIR"' EXIT mkdir -p ~/.local/share/fonts diff --git a/install_scripts/lib/dotinstaller/install-homebrew.sh b/install_scripts/lib/dotinstaller/install-homebrew.sh index 2b8c0e1..c4b75f0 100755 --- a/install_scripts/lib/dotinstaller/install-homebrew.sh +++ b/install_scripts/lib/dotinstaller/install-homebrew.sh @@ -29,7 +29,7 @@ function main() { local brew_commit="6d5e2670d07961e7985d2079a2f0a484420f3c38" local expected_sha256="dfd5145fe2aa5956a600e35848765273f5798ce6def01bd08ecec088a1268d91" local brew_script - brew_script=$(mktemp) + brew_script=$(mktemp -t brew_install.XXXXXX) trap 'rm -f "$brew_script"' EXIT curl -fsSL "https://raw.githubusercontent.com/Homebrew/install/${brew_commit}/install.sh" \