registry  /  rpi-deploy  /  0.10.0

rpi-deploy@0.10.0

Deployment tool for Docker Compose projects on Raspberry Pi. Builds the Rust CLI from source on install.

AI Security Review

scanned 17h ago · by lpm-firewall-ai

No confirmed malicious attack surface was found. Install-time behavior builds or installs the package's own CLI binary using package-aligned GitHub/rustup sources, and privileged agent/systemd mutation is behind explicit user commands.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
npm install runs postinstall; runtime actions require invoking rpi commands
Impact
Installs/builds rpi binary; no confirmed unauthorized exfiltration, persistence, or foreign AI-agent control mutation
Mechanism
package-owned native CLI install/build and explicit deployment agent management
Rationale
The risky primitives are visible and package-aligned: postinstall fetches/builds the package's own native binary, and agent/systemd mutations require explicit CLI setup. I found no hidden credential collection, stealth persistence, remote code execution chain beyond the disclosed install/build path, or unrelated control-surface modification.
Evidence
package.jsonscripts/postinstall.jsbin/rpi.jscrates/bin/src/main.rscrates/bin/src/agent/setup.rscrates/bin/src/agent/self_install.rscrates/bin/src/cli/commands.rscrates/bin/src/cli/api.rscrates/infrastructure/src/git.rsdist/rpidist/rpi.exetarget//usr/local/bin/rpi/etc/systemd/system/rpi-agent.service/etc/rpi/agent.toml/var/lib/rpi/var/log/rpi
Network endpoints4
github.com/khmilevoi/rpi-deploy/releases/download/v${version}/github.com/khmilevoi/rpi-deploy/releases/download/v${version}/SHA256SUMSwin.rustup.rs/${arch}sh.rustup.rs

Decision evidence

public snapshot
AI called this Clean at 82.0% confidence as Benign with high false-positive risk.
Evidence for block
  • package.json runs postinstall script
  • scripts/postinstall.js downloads release archive and SHA256SUMS from GitHub at install time
  • scripts/postinstall.js may run rustup installer when cargo is missing
  • scripts/postinstall.js runs tar and cargo build during package install
Evidence against
  • postinstall.js is limited to node_modules installs and skips source checkouts
  • prebuilt URL is package repository release for exact package version, not latest or obfuscated
  • archive hash is checked against SHA256SUMS before copying dist/rpi
  • bin/rpi.js only executes package-owned dist/rpi with user CLI args
  • Rust agent setup/systemd changes are explicit rpi agent setup commands, not install-time
  • No credential harvesting or exfiltration endpoint found
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetwork
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 3 file(s), 10.4 KB of source, external domains: github.com, rustup.rs, sh.rustup.rs, win.rustup.rs

Source & flagged code

7 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall.js
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node scripts/postinstall.js
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
bin/rpi.jsView file
5L6: const { spawnSync } = require('node:child_process'); L7: const fs = require('node:fs');
High
Child Process

Package source references child process execution.

bin/rpi.jsView on unpkg · L5
scripts/postinstall.jsView file
matchType = previous_version_dangerous_delta matchedPackage = rpi-deploy@0.6.0 matchedIdentity = npm:cnBpLWRlcGxveQ:0.6.0 similarity = 0.667 summary = stored previous version shares package body but lacks this dangerous source file
Critical
Previous Version Dangerous Delta

This package version adds a dangerous source file absent from the previous stored version; route for source-aware review.

scripts/postinstall.jsView on unpkg
8L9: const { spawnSync } = require('node:child_process'); L10: const fs = require('node:fs'); ... L13: L14: const pkgDir = path.resolve(__dirname, '..'); L15: const exe = process.platform === 'win32' ? '.exe' : ''; L16: const cargoBinDir = path.join(os.homedir(), '.cargo', 'bin'); ... L52: async function fetchTo(url, dest) { L53: const res = await fetch(url, { redirect: 'follow' }); L54: if (!res.ok) throw new Error(`download ${url}: HTTP ${res.status}`); L55: fs.writeFileSync(dest, Buffer.from(await res.arrayBuffer())); L56: }
High
Sandbox Evasion Gated Capability

Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.

scripts/postinstall.jsView on unpkg · L8
8L9: const { spawnSync } = require('node:child_process'); L10: const fs = require('node:fs'); ... L13: L14: const pkgDir = path.resolve(__dirname, '..'); L15: const exe = process.platform === 'win32' ? '.exe' : ''; L16: const cargoBinDir = path.join(os.homedir(), '.cargo', 'bin'); ... L52: async function fetchTo(url, dest) { L53: const res = await fetch(url, { redirect: 'follow' }); L54: if (!res.ok) throw new Error(`download ${url}: HTTP ${res.status}`); L55: fs.writeFileSync(dest, Buffer.from(await res.arrayBuffer())); L56: }
High
Install Named Payload File

Install-named source file stages remote content through filesystem writes and execution.

scripts/postinstall.jsView on unpkg · L8
152fs.writeFileSync(tmp, Buffer.from(await res.arrayBuffer())); L153: const r = spawnSync(tmp, ['-y'], { stdio: 'inherit' }); L154: if (r.status !== 0) fail('rustup-init failed'); ... L156: if (!which('curl')) { L157: fail('curl is required to install rustup; install curl, then rerun: npm install -g rpi-deploy'); L158: }
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

scripts/postinstall.jsView on unpkg · L152

Findings

1 Critical5 High4 Medium5 Low
CriticalPrevious Version Dangerous Deltascripts/postinstall.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processbin/rpi.js
HighSandbox Evasion Gated Capabilityscripts/postinstall.js
HighInstall Named Payload Filescripts/postinstall.js
HighRuntime Package Installscripts/postinstall.js
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings