Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ tree-sitter-ruby = { version = "0.23", optional = true }
tree-sitter-php = { version = "0.24", optional = true }
tree-sitter-scala = { version = "0.26", optional = true }
tree-sitter-javascript = { version = "0.25", optional = true }
tempfile = "3"

[features]
default = ["tree-sitter"]
Expand All @@ -116,7 +117,6 @@ tree-sitter = [
[dev-dependencies]
assert_cmd = "2"
predicates = "3"
tempfile = "3"
tokio-test = "0.4"

[profile.release]
Expand Down
44 changes: 32 additions & 12 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -109,21 +109,32 @@ install() {
fi

# Verify SHA256 checksum (prevents MITM / corrupted download).
info "Downloading checksums..."
if curl -fsSL "$CHECKSUMS_URL" -o "$CHECKSUM_FILE"; then
# Mandatory: a missing checksums file or entry is fatal unless the user
# explicitly opts out with CORA_SKIP_CHECKSUM=1.
if [ "${CORA_SKIP_CHECKSUM:-}" = "1" ]; then
warn "CORA_SKIP_CHECKSUM=1 set - checksum verification DISABLED. The binary is NOT verified."
else
info "Downloading checksums..."
if ! curl -fsSL "$CHECKSUMS_URL" -o "$CHECKSUM_FILE"; then
error "Failed to download checksums. Refusing to install an unverified binary (set CORA_SKIP_CHECKSUM=1 to override, unsafe)."
fi
info "Verifying SHA256 checksum..."
EXPECTED=$(grep -F "$ARCHIVE_NAME" "$CHECKSUM_FILE" | awk '{print $1}')
if [ -n "$EXPECTED" ]; then
# Exact filename match (optionally prefixed with '*' or './').
EXPECTED=$(awk -v n="$ARCHIVE_NAME" '{f=$2; sub(/^\*/, "", f); sub(/^\.\//, "", f); if (f == n) {print $1; exit}}' "$CHECKSUM_FILE")
if [ -z "$EXPECTED" ]; then
error "Checksum for ${ARCHIVE_NAME} not found in checksums file. Refusing to install (set CORA_SKIP_CHECKSUM=1 to override, unsafe)."
fi
if command -v sha256sum >/dev/null 2>&1; then
ACTUAL=$(sha256sum "$ARCHIVE" | awk '{print $1}')
if [ "$ACTUAL" != "$EXPECTED" ]; then
error "Checksum mismatch! Expected: ${EXPECTED}, got: ${ACTUAL}"
fi
info "Checksum verified: $EXPECTED"
elif command -v shasum >/dev/null 2>&1; then
ACTUAL=$(shasum -a 256 "$ARCHIVE" | awk '{print $1}')
else
warn "Checksum for ${ARCHIVE_NAME} not found in checksums file — skipping verification"
error "Neither sha256sum nor shasum found; cannot verify checksum (set CORA_SKIP_CHECKSUM=1 to override, unsafe)."
fi
else
warn "Failed to download checksums — skipping verification"
if [ "$ACTUAL" != "$EXPECTED" ]; then
error "Checksum mismatch! Expected: ${EXPECTED}, got: ${ACTUAL}"
fi
info "Checksum verified: $EXPECTED"
fi

# Verify archive contents before extraction (CWE-22 path traversal).
Expand All @@ -133,8 +144,17 @@ install() {
error "Archive contains unsafe paths (absolute or directory traversal) — refusing to extract"
fi

# Reject symlink/hardlink entries (first char of the verbose mode string:
# 'l' = symlink; bsdtar lists hardlinks with 'h').
if tar -tvzf "$ARCHIVE" | grep -qE '^[lh]'; then
error "Archive contains symlink/hardlink entries - refusing to extract"
fi

info "Extracting..."
tar -xzf "$ARCHIVE" -C "$TEMP_DIR"
# Extract only the single binary entry (tolerate an optional ./ prefix).
tar -xzf "$ARCHIVE" -C "$TEMP_DIR" "${BINARY_NAME}" 2>/dev/null \
|| tar -xzf "$ARCHIVE" -C "$TEMP_DIR" "./${BINARY_NAME}" \
|| error "Binary '${BINARY_NAME}' not found in archive"

mkdir -p "$INSTALL_DIR"
mv "${TEMP_DIR}/${BINARY_NAME}" "${INSTALL_DIR}/"
Expand Down
Loading
Loading