factory-cli-bin
Triggered rules
external_download_not_in_source
curl/wget fetches a URL on a non-allowlisted host that is not part of source=(), so it is not checksum-verified by makepkg.
-
PKGBUILD:30
actual_version=$(curl -fsSL "https://app.factory.ai/cli" | grep -oP 'VER="\K[0-9]+\.[0-9]+\.[0-9]+')
llm_review
The static rules flagged this HIGH, but an AI model (anthropic/claude-4.6-sonnet-20260217) reviewed the full PKGBUILD and judged it MEDIUM (confidence 82%): This PKGBUILD downloads pre-compiled binaries at install time from downloads.factory.ai (an unofficial/vendor-controlled host) without declaring them in source=() or providing fixed sha256sums in the PKGBUILD itself. The version is dynamically fetched by curling app.factory.ai/cli at build time, meaning the version and download URLs are entirely controlled by the remote server at package() execution time. While the PKGBUILD does perform sha256 verification against checksums also fetched from the same server (making the verification trivially bypassable by the same attacker who controls the server), the binaries are installed but NOT executed during the build process itself - they are only installed to pkgdir. The flagged 'executed file' at line 149 is actually `install -Dm755 'droid' ...` which installs but does not execute the binary. The core concern is: (1) no reproducibility - the package content can change silently between builds since source=() is empty and no fixed hashes exist in the PKGBUILD; (2) the checksum oracle is the same host serving the binary, providing no real integrity guarantee against a compromised server; (3) binaries are closed-source from a commercial vendor. This is a medium supply-chain risk (unverifiable binary from a vendor host with no pinned hashes) but not clearly malicious RCE or exfiltration.
1 higher static finding superseded - not the current verdict (shown for transparency)
download_then_exec
A file fetched with curl/wget (not part of source=(), so never checksum-verified) is later made executable or run — a fetch-and-execute pattern split across statements.
-
PKGBUILD:149
chmod 755 "$pkgdir/usr/bin/droid"
PKGBUILD
2 offending line(s) highlighted# Maintainer: alex5402 <alexbhaiya@duck.com>
pkgname=factory-cli-bin
pkgver=1.0.2
pkgrel=1
pkgdesc="Factory CLI - AI-powered terminal assistant"
arch=('x86_64' 'aarch64')
url="https://app.factory.ai"
license=('factory.ai')
depends=('curl')
optdepends=('ripgrep: Use system ripgrep instead of bundled version')
provides=('droid')
conflicts=('droid')
options=('!strip')
install="${pkgname}.install"
# Sources will be downloaded dynamically in package() function
source=()
sha256sums=()
pkgver() {
# Fetch the install script and extract the version
curl -fsSL "https://app.factory.ai/cli" | grep -oP 'VER="\K[0-9]+\.[0-9]+\.[0-9]+' || echo "1.0.0"
}
package() {
cd "$srcdir"
# Get the actual version from the install script
local actual_version
actual_version=$(curl -fsSL "https://app.factory.ai/cli" | grep -oP 'VER="\K[0-9]+\.[0-9]+\.[0-9]+')
if [[ -z "$actual_version" ]]; then
error "Failed to fetch version from install script"
return 1
fi
msg2 "Detected Factory CLI version: $actual_version"
# Detect platform (always linux for Arch)
local platform="linux"
# Detect architecture
local architecture rg_architecture arch_suffix
case "$CARCH" in
x86_64)
architecture="x64"
;;
aarch64)
architecture="arm64"
;;
*)
error "Unsupported architecture: $CARCH"
return 1
;;
esac
# Detect AVX2 support for x64 (for optimized droid binary)
rg_architecture="$architecture"
arch_suffix=""
if [[ "$architecture" == "x64" ]]; then
if grep -qi avx2 /proc/cpuinfo 2>/dev/null; then
msg2 "AVX2 support detected, using optimized binary"
else
arch_suffix="-baseline"
msg2 "No AVX2 support detected, using baseline binary"
fi
fi
local droid_architecture="${architecture}${arch_suffix}"
# Construct download URLs using the actual version
local base_url="https://downloads.factory.ai"
local droid_url="$base_url/factory-cli/releases/$actual_version/$platform/$droid_architecture/droid"
local droid_sha_url="$base_url/factory-cli/releases/$actual_version/$platform/$droid_architecture/droid.sha256"
local rg_url="$base_url/ripgrep/$platform/$rg_architecture/rg"
local rg_sha_url="$base_url/ripgrep/$platform/$rg_architecture/rg.sha256"
# Download droid binary
msg2 "Downloading droid for $platform-$droid_architecture..."
curl -fsSL -o "droid" "$droid_url" || {
error "Failed to download droid from $droid_url"
return 1
}
# Download and verify droid checksum
msg2 "Verifying droid checksum..."
curl -fsSL -o "droid.sha256" "$droid_sha_url" || {
error "Failed to download droid checksum"
return 1
}
local expected_sha actual_sha
expected_sha=$(awk '{print $1}' "droid.sha256")
actual_sha=$(sha256sum "droid" | awk '{print $1}')
if [[ -n "$expected_sha" && "$expected_sha" != "$actual_sha" ]]; then
error "Droid checksum verification failed!"
error "Expected: $expected_sha"
error "Actual: $actual_sha"
return 1
fi
msg2 "Droid checksum verified successfully"
# Download ripgrep binary
msg2 "Downloading ripgrep for $platform-$rg_architecture..."
curl -fsSL -o "rg" "$rg_url" || {
error "Failed to download ripgrep from $rg_url"
return 1
}
# Download and verify ripgrep checksum
msg2 "Verifying ripgrep checksum..."
curl -fsSL -o "rg.sha256" "$rg_sha_url" || {
error "Failed to download ripgrep checksum"
return 1
}
local expected_rg_sha actual_rg_sha
expected_rg_sha=$(awk '{print $1}' "rg.sha256")
actual_rg_sha=$(sha256sum "rg" | awk '{print $1}')
if [[ -n "$expected_rg_sha" && "$expected_rg_sha" != "$actual_rg_sha" ]]; then
error "Ripgrep checksum verification failed!"
error "Expected: $expected_rg_sha"
error "Actual: $actual_rg_sha"
return 1
fi
msg2 "Ripgrep checksum verified successfully"
# Create installation directories
install -dm755 "$pkgdir/usr/lib/factory"
install -dm755 "$pkgdir/usr/bin"
# Install binaries to /usr/lib/factory
install -Dm755 "droid" "$pkgdir/usr/lib/factory/droid"
install -Dm755 "rg" "$pkgdir/usr/lib/factory/rg"
# Create wrapper script in /usr/bin
# This ensures the bundled ripgrep is used only for droid
cat > "$pkgdir/usr/bin/droid" <<'EOF'
#!/bin/sh
# Factory CLI wrapper
# Ensures bundled ripgrep is preferred for this tool
export PATH="/usr/lib/factory:$PATH"
exec /usr/lib/factory/droid "$@"
EOF
chmod 755 "$pkgdir/usr/bin/droid"
# Install license if available (create placeholder for now)
install -dm755 "$pkgdir/usr/share/licenses/$pkgname"
cat > "$pkgdir/usr/share/licenses/$pkgname/LICENSE" <<EOF
Factory CLI License
Please visit https://factory.ai for license information.
EOF
msg2 "Factory CLI (droid) v$actual_version installed successfully"
}
Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-08-03 00:08:14 | MEDIUM | 3 |
| 2026-08-02 00:16:08 | MEDIUM | 3 |
| 2026-08-01 00:11:18 | MEDIUM | 3 |
| 2026-07-31 00:14:10 | MEDIUM | 3 |
| 2026-07-30 00:17:23 | MEDIUM | 3 |
| 2026-07-29 00:25:53 | MEDIUM | 3 |
| 2026-07-28 00:07:28 | MEDIUM | 3 |
| 2026-07-27 00:24:32 | MEDIUM | 3 |
| 2026-07-26 00:07:32 | MEDIUM | 3 |
| 2026-07-25 00:13:44 | MEDIUM | 3 |
| 2026-07-24 00:02:28 | MEDIUM | 3 |
| 2026-07-23 00:14:47 | MEDIUM | 3 |
| 2026-07-22 00:29:32 | MEDIUM | 3 |
| 2026-07-21 00:24:15 | MEDIUM | 3 |
| 2026-07-20 00:19:49 | MEDIUM | 3 |
| 2026-07-19 00:17:08 | MEDIUM | 3 |
| 2026-07-18 00:14:48 | MEDIUM | 3 |
| 2026-07-17 00:06:16 | MEDIUM | 3 |
| 2026-07-16 00:05:41 | MEDIUM | 3 |
| 2026-07-15 00:09:25 | MEDIUM | 3 |