Skip to content

security: add checksum verification and safe .env parser (v0.1.3)#27

Merged
canoo merged 5 commits intocanoo:mainfrom
anakinMango:feature/v0.1.3-security-hardening
Apr 24, 2026
Merged

security: add checksum verification and safe .env parser (v0.1.3)#27
canoo merged 5 commits intocanoo:mainfrom
anakinMango:feature/v0.1.3-security-hardening

Conversation

@anakinMango
Copy link
Copy Markdown
Collaborator

@anakinMango anakinMango commented Apr 23, 2026

Summary

Closes #6 and #7 — completes the v0.1.3 Security Hardening milestone.

Changes

install.sh — checksum verification (fixes #6)

GoReleaser publishes checksums.txt alongside each release binary. This change:

  • Downloads checksums.txt from the same release tag
  • Extracts the expected SHA256 for the platform binary
  • Verifies with sha256sum (Linux) or shasum -a 256 (macOS)
  • Fails hard and removes the binary if verification fails
  • Warns (but continues) if neither tool is available

tools/automation/ollama-delegate.sh — safe .env parser (fixes #7)

Replaces source .env with a line-by-line parser (_load_env) that:

  • Skips blank lines and comments
  • Rejects any line containing $( or backticks
  • Accepts only KEY=VALUE lines matching [A-Za-z_][A-Za-z0-9_]*=
  • Strips surrounding single/double quotes from values
  • Uses export to set each variable

Testing

  • Both files pass bash -n syntax check
  • Checksum path tested against a real release asset URL pattern
  • .env parser rejects FOO=$(rm -rf /) and BAR=`whoami` style injections

Summary by CodeRabbit

  • Bug Fixes

    • Safer environment file handling: ignores comments/blank lines, strips surrounding quotes, warns on unsafe constructs, and prevents execution of arbitrary shell content.
  • Chores

    • Installer integrity checks: downloads release checksums and verifies installers with SHA-256, fails on missing/mismatched entries, cleans temporary files, and warns if verification tools are absent.

@canoo canoo self-requested a review April 23, 2026 19:58
- install.sh: download checksums.txt from the same release and verify
  the binary SHA256 before chmod+x; fail hard on mismatch (fixes canoo#6)
- ollama-delegate.sh: replace `source .env` with a line-by-line parser
  that rejects command substitution and backticks (fixes canoo#7)
@anakinMango anakinMango force-pushed the feature/v0.1.3-security-hardening branch from 4c58a99 to fad8bfb Compare April 23, 2026 20:01
canoo
canoo previously requested changes Apr 23, 2026
Copy link
Copy Markdown
Owner

@canoo canoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid PR — both fixes address real security risks with clean implementations. One issue to fix before merge.

ollama-delegate.sh — The _load_env() parser is exactly what #7 asked for. Rejects command substitution, validates key format, strips quotes. Clean.

install.sh — Checksum verification logic is sound. The sha256sum/shasum fallback and the soft-fail when neither tool is available are reasonable choices. One bug to fix (see inline comment).

Design note: the soft-fail path (warn + continue when no hash tool is available) is a conscious tradeoff — don't break installs on minimal systems. That's fine for now.

Comment thread install.sh
Comment thread install.sh
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 23, 2026

📝 Walkthrough

Walkthrough

install.sh downloads checksums.txt and verifies the downloaded binary's SHA-256 hash (using sha256sum or shasum -a 256), failing on missing or mismatched entries or if no hash tool is available; tools/automation/ollama-delegate.sh replaces source .env with a safer parser that exports only simple KEY=VALUE lines and warns on unsafe syntax.

Changes

Cohort / File(s) Summary
Binary Integrity Verification
install.sh
Downloads checksums.txt alongside the platform binary, extracts the expected SHA-256 for nexus-${OS}-${ARCH}, verifies via sha256sum --check --status or shasum -a 256 --check --status; on missing entry, verification failure, or absence of both tools it deletes downloaded files and fails; removes temporary checksum file on success.
Safer Environment Variable Loading
tools/automation/ollama-delegate.sh
Replaces source .env with a custom _load_env parser: ignores blanks/comments, exports only simple KEY=VALUE assignments, strips matching surrounding quotes, and skips+warns on lines with command substitution ($()), backticks, or other unsafe syntax.

Sequence Diagram(s)

sequenceDiagram
  participant Installer as Installer (install.sh)
  participant Remote as Release Server (GitHub)
  participant FS as Filesystem
  participant Verifier as Hash Tool (sha256sum / shasum)

  Installer->>Remote: GET nexus-${OS}-${ARCH}
  Installer->>Remote: GET checksums.txt
  Remote-->>Installer: binary + checksums.txt
  Installer->>FS: save binary, save checksums.txt
  Installer->>FS: extract expected hash for binary
  Installer->>Verifier: run checksum verification
  Verifier-->>Installer: OK / FAIL
  alt OK
    Installer->>FS: remove checksums.txt
    Installer-->>Installer: print success (verified)
  else FAIL
    Installer->>FS: remove binary and checksums.txt
    Installer-->>Installer: abort install (verification failed)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped to fetch bytes from the hill,
A checksum in paw to guard every thrill,
I read .env with careful eyes, no tricks in play,
Now binaries and vars sleep safe till day,
Carrots, checks, and quiet builds — hooray! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding checksum verification and a safe .env parser for security hardening.
Linked Issues check ✅ Passed Both issues #6 and #7 are fully addressed: install.sh downloads and verifies checksums, and ollama-delegate.sh replaces unsafe sourcing with a safe parser.
Out of Scope Changes check ✅ Passed All changes are directly related to the two linked security issues; no out-of-scope modifications were introduced.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@install.sh`:
- Around line 92-94: The installer currently logs a warning when neither
sha256sum nor shasum is available (the else branch that calls warn "Neither
sha256sum nor shasum found — skipping checksum verification"); change this to
fail closed by emitting an explicit error and aborting the install (exit
non‑zero) so the script does not continue without checksum verification —
replace the warn call with a fatal/error path (use the existing die/error
function if present, otherwise call echo >&2 and exit 1) in the same conditional
that checks for sha256sum/shasum.
- Around line 73-76: When a checksum entry is missing or a verification fails,
the script currently leaves the downloaded binary on disk; update the failure
branches that check "if [ -z \"$expected\" ]" and the later checksum-failure
block to also remove the downloaded binary by adding a safe, quoted removal
(e.g. rm -f "$binary_file") alongside rm -f "$checksum_file"; use the existing
variables binary_name, checksum_file and binary_file and ensure all variable
expansions are quoted to avoid accidental word-splitting or globbing.

In `@tools/automation/ollama-delegate.sh`:
- Around line 45-48: The current logic unconditionally strips leading and
trailing quotes from the variable value (see the manipulations of value), which
can corrupt strings when quotes don't match; change it to only remove
surrounding quotes when both the first and last characters are matching quotes
(either both " or both '): detect the first and last char of value, and if they
are both double-quotes or both single-quotes, strip them; otherwise leave value
untouched; apply this check where value is currently being trimmed.
- Around line 36-38: Replace the stderr log that prints the raw rejected line
(the echo referencing $line) so secrets are not leaked: add and maintain a line
counter (e.g., lineno incremented each loop) and change the warning to only emit
metadata such as "WARN: Skipping unsafe .env line at line $lineno" (do not
include or expand $line), leaving the continue in place; ensure the read loop
uses safe read -r and the new warning only outputs the line number or other
non-sensitive context.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 433c5dc0-3533-4f4c-9d67-bcdb1eb3640b

📥 Commits

Reviewing files that changed from the base of the PR and between 043c387 and 6d4a57e.

📒 Files selected for processing (2)
  • install.sh
  • tools/automation/ollama-delegate.sh

Comment thread install.sh
Comment thread install.sh
Comment thread tools/automation/ollama-delegate.sh
Comment thread tools/automation/ollama-delegate.sh Outdated
- install.sh: anchor grep with ^binary_name to prevent substring matches
- install.sh: remove dest binary on checksum-missing failure paths
- ollama-delegate.sh: log line number instead of raw content on unsafe line
- ollama-delegate.sh: guard quote stripping to matching surrounding pairs only
@anakinMango anakinMango force-pushed the feature/v0.1.3-security-hardening branch from 6d4a57e to 1c9b5b2 Compare April 23, 2026 22:22
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tools/automation/ollama-delegate.sh`:
- Around line 47-48: The current quoted-value trimming uses a Bash 4.x
negative-length expansion (value="${value:1:-1}") which fails on macOS Bash 3.2;
change the logic inside the quoted branch that operates on the variable value to
first take the substring from index 1 onward and then remove the final character
(i.e., strip the leading quote, then strip the trailing quote) using POSIX/Bash
3.2-compatible parameter expansions (take value from offset 1, then remove its
last character via a trailing-pattern removal), so the quoted branch that checks
value with the regexes still ends up with the unquoted content but without using
negative-length expansions.
🪄 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 Plus

Run ID: e65723dd-9e26-4542-8abf-f037eda9b1b4

📥 Commits

Reviewing files that changed from the base of the PR and between 6d4a57e and 1c9b5b2.

📒 Files selected for processing (2)
  • install.sh
  • tools/automation/ollama-delegate.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • install.sh

Comment thread tools/automation/ollama-delegate.sh Outdated
${value:1:-1} negative substring length is unsupported in Bash 3.2
(macOS default). Replace with case + # / % parameter expansions.
@anakinMango anakinMango force-pushed the feature/v0.1.3-security-hardening branch from 4188c93 to bf568dd Compare April 24, 2026 06:43
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/automation/ollama-delegate.sh (1)

55-55: Use BASH_SOURCE[0] for stable .env path resolution.

$(dirname "$0") can resolve unexpectedly depending on invocation style. Prefer resolving from BASH_SOURCE[0] to reliably target repo-root .env.

♻️ Suggested fix
-_load_env "$(dirname "$0")/../../.env"
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
+_load_env "${SCRIPT_DIR}/../../.env"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/automation/ollama-delegate.sh` at line 55, Replace the unstable
"$(dirname "$0")/../../.env" invocation passed to _load_env with a path resolved
from BASH_SOURCE[0]; specifically, update the _load_env call that currently uses
"$0" so it uses "${BASH_SOURCE[0]}" (and keep proper quoting and dirname usage)
to reliably resolve the repo-root .env. Ensure the change targets the existing
_load_env invocation and preserves the surrounding dirname and ../../.env path
traversal.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tools/automation/ollama-delegate.sh`:
- Around line 43-52: The current loop that parses lines and exports variables
(matching the regex and using local key="${line%%=*}" and export "$key=$value")
should be restricted to an allowlist to prevent exporting dangerous variables
like PATH or IFS; modify the code so after extracting key and value you check
key against a predefined allowlist (e.g., an array or a regex of permitted
names) and only perform export "$key=$value" when the key is in that allowlist,
otherwise skip or log/ignore the entry—apply this change in the block that
handles the case stripping and before the export.

---

Nitpick comments:
In `@tools/automation/ollama-delegate.sh`:
- Line 55: Replace the unstable "$(dirname "$0")/../../.env" invocation passed
to _load_env with a path resolved from BASH_SOURCE[0]; specifically, update the
_load_env call that currently uses "$0" so it uses "${BASH_SOURCE[0]}" (and keep
proper quoting and dirname usage) to reliably resolve the repo-root .env. Ensure
the change targets the existing _load_env invocation and preserves the
surrounding dirname and ../../.env path traversal.
🪄 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 Plus

Run ID: 05d96903-71f0-4f11-bf07-819099e6f373

📥 Commits

Reviewing files that changed from the base of the PR and between 1c9b5b2 and bf568dd.

📒 Files selected for processing (1)
  • tools/automation/ollama-delegate.sh

Comment on lines +43 to +52
if [[ "$line" =~ ^[A-Za-z_][A-Za-z0-9_]*= ]]; then
local key="${line%%=*}"
local value="${line#*=}"
# Strip surrounding quotes only if they match as a pair (Bash 3.2 portable)
case "$value" in
\"*\") value="${value#\"}"; value="${value%\"}" ;;
\'*\') value="${value#\'}"; value="${value%\'}" ;;
esac
export "$key=$value"
fi
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 | 🟠 Major

Restrict allowed .env keys before export to prevent environment poisoning.

Lines 43-52 currently export any syntactically valid key. That allows .env entries like PATH=... / IFS=... to influence later command execution and weaken the security objective.

🔒 Suggested fix (allowlist keys)
         if [[ "$line" =~ ^[A-Za-z_][A-Za-z0-9_]*= ]]; then
             local key="${line%%=*}"
             local value="${line#*=}"
+            case "$key" in
+                OLLAMA_HOST_URL|NEXUS_* ) ;;
+                *)
+                    echo "WARN: Ignoring unsupported .env key at line ${lineno}" >&2
+                    continue
+                    ;;
+            esac
             # Strip surrounding quotes only if they match as a pair (Bash 3.2 portable)
             case "$value" in
                 \"*\") value="${value#\"}"; value="${value%\"}" ;;
                 \'*\') value="${value#\'}"; value="${value%\'}" ;;
             esac
             export "$key=$value"
         fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/automation/ollama-delegate.sh` around lines 43 - 52, The current loop
that parses lines and exports variables (matching the regex and using local
key="${line%%=*}" and export "$key=$value") should be restricted to an allowlist
to prevent exporting dangerous variables like PATH or IFS; modify the code so
after extracting key and value you check key against a predefined allowlist
(e.g., an array or a regex of permitted names) and only perform export
"$key=$value" when the key is in that allowlist, otherwise skip or log/ignore
the entry—apply this change in the block that handles the case stripping and
before the export.

Copy link
Copy Markdown
Owner

@canoo canoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All original review items addressed. The grep anchoring is fixed, binary cleanup on failure is solid, and the .env parser handles secrets and quotes correctly now.

One last suggestion inline for the soft-fail → hard-fail change. Apply it and this is ready to merge.

Nice work on the Bash 3.2 compatibility fix for quote stripping — that was a good catch.

Comment thread install.sh
@canoo canoo dismissed their stale review April 24, 2026 06:56

grep fixes applied, moving to approval

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

♻️ Duplicate comments (1)
install.sh (1)

81-91: ⚠️ Potential issue | 🔴 Critical

Same syntax and logic errors in shasum fallback block.

Lines 83-87 have the same issues as the sha256sum block above: duplicate expected= assignment (lines 83/84), missing if [ -z "$expected" ]; then, and wrong grep pattern.

🐛 Proposed fix
     elif command -v shasum &>/dev/null; then
         local expected
-        expected=$(grep "^${binary_name} " "$checksum_file" | awk '{print $1}')
-    expected=$(grep "^${binary_name} " "$checksum_file" | awk '{print $1}')
+        expected=$(grep " ${binary_name}$" "$checksum_file" | awk '{print $1}')
+        if [ -z "$expected" ]; then
             rm -f "$dest" "$checksum_file"
             fail "Checksum entry for $binary_name not found in checksums.txt"
         fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@install.sh` around lines 81 - 91, In the shasum fallback block, remove the
duplicated expected= assignment and replace the fragile grep+awk with a single,
reliable lookup that finds the checksum by matching the filename column; for
example set expected by running awk to check $2==binary_name and print $1 (e.g.
expected=$(awk -v name="$binary_name" '$2==name {print $1; exit}'
"$checksum_file")), then add the missing if [ -z "$expected" ]; then rm -f
"$dest" "$checksum_file" && fail "Checksum entry for $binary_name not found in
checksums.txt" fi before running shasum -a 256 --check --status so the script
fails early when no entry is found and uses the correct checksum value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@install.sh`:
- Around line 69-80: The sha256sum verification block is broken: remove the
duplicate expected=$(grep ...) line, add a proper check for an empty expected
(if [ -z "$expected" ]; then ... fi) before using it, and fix the grep to match
filename at end of line (e.g. grep "<pattern matching filename at end>"
"$checksum_file" to extract the hash into the variable expected) so that when
expected is empty you run rm -f "$dest" "$checksum_file" and call fail "Checksum
entry for $binary_name not found in checksums.txt", otherwise echo "$expected 
$dest" | sha256sum --check --status || { rm -f "$dest" "$checksum_file"; fail
"Checksum verification failed — binary may be corrupted or tampered with"; }
referencing the variables binary_name, checksum_file, expected, dest and the
sha256sum verification block.
- Around line 92-97: The else branch inside the checksum selection block should
not emit a misleading warn and must be closed: remove the redundant warn
"Neither sha256sum nor shasum found — skipping checksum verification" and keep
the fail call that aborts ("fail 'Neither sha256sum nor shasum found — cannot
verify binary integrity. Install coreutils and retry.'"), then add the missing
fi to close the if/elif/else block that begins around the checksum detection,
and ensure the standalone rm -f "$checksum_file" that follows is
positioned/executed only on the successful path after that fi (i.e., leave the
cleanup rm for the success flow, not inside the else).

---

Duplicate comments:
In `@install.sh`:
- Around line 81-91: In the shasum fallback block, remove the duplicated
expected= assignment and replace the fragile grep+awk with a single, reliable
lookup that finds the checksum by matching the filename column; for example set
expected by running awk to check $2==binary_name and print $1 (e.g.
expected=$(awk -v name="$binary_name" '$2==name {print $1; exit}'
"$checksum_file")), then add the missing if [ -z "$expected" ]; then rm -f
"$dest" "$checksum_file" && fail "Checksum entry for $binary_name not found in
checksums.txt" fi before running shasum -a 256 --check --status so the script
fails early when no entry is found and uses the correct checksum value.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: be4b2a7b-a570-410b-afc7-56a55b6060ed

📥 Commits

Reviewing files that changed from the base of the PR and between bf568dd and 12876f6.

📒 Files selected for processing (1)
  • install.sh

Comment thread install.sh
Comment on lines +69 to +80
if command -v sha256sum &>/dev/null; then
# Extract expected hash for this binary and verify
local expected
expected=$(grep "^${binary_name} " "$checksum_file" | awk '{print $1}')
expected=$(grep "^${binary_name} " "$checksum_file" | awk '{print $1}')
rm -f "$dest" "$checksum_file"
fail "Checksum entry for $binary_name not found in checksums.txt"
fi
echo "$expected $dest" | sha256sum --check --status || {
rm -f "$dest" "$checksum_file"
fail "Checksum verification failed — binary may be corrupted or tampered with"
}
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 | 🔴 Critical

Critical syntax and logic errors in sha256sum verification block.

Multiple issues that will break the script:

  1. Duplicate line: Lines 72 and 73 are identical — the second expected= assignment is redundant.
  2. Missing conditional: Lines 74-76 have rm -f, fail, and fi but no corresponding if [ -z "$expected" ]; then statement. This is a syntax error.
  3. Wrong grep pattern: The pattern "^${binary_name} " looks for the filename at the start of each line, but GoReleaser produces <hash> <filename> format (hash first, two spaces, then filename). The pattern should match the filename at the end of the line.
🐛 Proposed fix
     if command -v sha256sum &>/dev/null; then
         # Extract expected hash for this binary and verify
         local expected
-        expected=$(grep "^${binary_name} " "$checksum_file" | awk '{print $1}')
-        expected=$(grep "^${binary_name} " "$checksum_file" | awk '{print $1}')
+        expected=$(grep " ${binary_name}$" "$checksum_file" | awk '{print $1}')
+        if [ -z "$expected" ]; then
             rm -f "$dest" "$checksum_file"
             fail "Checksum entry for $binary_name not found in checksums.txt"
         fi
📝 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
if command -v sha256sum &>/dev/null; then
# Extract expected hash for this binary and verify
local expected
expected=$(grep "^${binary_name} " "$checksum_file" | awk '{print $1}')
expected=$(grep "^${binary_name} " "$checksum_file" | awk '{print $1}')
rm -f "$dest" "$checksum_file"
fail "Checksum entry for $binary_name not found in checksums.txt"
fi
echo "$expected $dest" | sha256sum --check --status || {
rm -f "$dest" "$checksum_file"
fail "Checksum verification failed — binary may be corrupted or tampered with"
}
if command -v sha256sum &>/dev/null; then
# Extract expected hash for this binary and verify
local expected
expected=$(grep " ${binary_name}$" "$checksum_file" | awk '{print $1}')
if [ -z "$expected" ]; then
rm -f "$dest" "$checksum_file"
fail "Checksum entry for $binary_name not found in checksums.txt"
fi
echo "$expected $dest" | sha256sum --check --status || {
rm -f "$dest" "$checksum_file"
fail "Checksum verification failed — binary may be corrupted or tampered with"
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@install.sh` around lines 69 - 80, The sha256sum verification block is broken:
remove the duplicate expected=$(grep ...) line, add a proper check for an empty
expected (if [ -z "$expected" ]; then ... fi) before using it, and fix the grep
to match filename at end of line (e.g. grep "<pattern matching filename at end>"
"$checksum_file" to extract the hash into the variable expected) so that when
expected is empty you run rm -f "$dest" "$checksum_file" and call fail "Checksum
entry for $binary_name not found in checksums.txt", otherwise echo "$expected 
$dest" | sha256sum --check --status || { rm -f "$dest" "$checksum_file"; fail
"Checksum verification failed — binary may be corrupted or tampered with"; }
referencing the variables binary_name, checksum_file, expected, dest and the
sha256sum verification block.

Comment thread install.sh
Comment on lines +92 to +97
else
warn "Neither sha256sum nor shasum found — skipping checksum verification"
rm -f "$dest" "$checksum_file"
fail "Neither sha256sum nor shasum found — cannot verify binary integrity. Install coreutils and retry."

rm -f "$checksum_file"
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 | 🔴 Critical

Missing fi and redundant warn in else block.

  1. Redundant warn: Line 93 says "skipping checksum verification" but line 95 immediately fails. The warn is misleading and unnecessary since we're aborting.
  2. Missing fi: The if/elif/else block starting at line 69 is never closed. Line 97 (rm -f "$checksum_file") should execute only on the success path after the block ends, but without fi this is a syntax error.
🐛 Proposed fix
     else
-        warn "Neither sha256sum nor shasum found — skipping checksum verification"
         rm -f "$dest" "$checksum_file"
         fail "Neither sha256sum nor shasum found — cannot verify binary integrity. Install coreutils and retry."
-
+    fi
+
     rm -f "$checksum_file"
     chmod +x "$dest"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@install.sh` around lines 92 - 97, The else branch inside the checksum
selection block should not emit a misleading warn and must be closed: remove the
redundant warn "Neither sha256sum nor shasum found — skipping checksum
verification" and keep the fail call that aborts ("fail 'Neither sha256sum nor
shasum found — cannot verify binary integrity. Install coreutils and retry.'"),
then add the missing fi to close the if/elif/else block that begins around the
checksum detection, and ensure the standalone rm -f "$checksum_file" that
follows is positioned/executed only on the successful path after that fi (i.e.,
leave the cleanup rm for the success flow, not inside the else).

@anakinMango anakinMango force-pushed the feature/v0.1.3-security-hardening branch from 12876f6 to ac8a88a Compare April 24, 2026 07:15
@canoo canoo merged commit 8fe1724 into canoo:main Apr 24, 2026
4 checks passed
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.

Use safer .env parser in ollama-delegate.sh Add checksum verification to install.sh

2 participants