AI Security Review
scanned 2h ago · by lpm-firewall-aiNo confirmed malicious attack surface was found. The postinstall is an install-time native dependency rebuild workaround, and runtime behavior is a documented Gmail sent-mail-to-local-ledger adapter.
Static reason
High-risk behavior combination matched malicious policy.
Trigger
npm install runs postinstall; user-invoked usrcp-gmail starts polling after setup
Impact
Reads configured user's sent Gmail messages and stores bounded metadata/body in the local USRCP ledger when run by the user
Mechanism
package-aligned Gmail readonly polling and local ledger append
Rationale
Static inspection found risky primitives, but they are narrow and package-aligned: postinstall rebuilds better-sqlite3, while runtime reads user-provided Gmail credentials to poll sent messages into a local ledger. There is no evidence of credential exfiltration, persistence, remote payload execution, or unconsented AI-agent control-surface mutation.
Evidence
package.jsondist/index.jsdist/reader.jsdist/config.jsdist/capture.jsdist/setup.jsREADME.mdnode_modules/better-sqlite3/buildnode_modules/usrcp-core/node_modules/better-sqlite3/buildnode_modules/usrcp-stream/node_modules/better-sqlite3/build~/.usrcp/gmail-config.json
Network endpoints3
www.googleapis.com/auth/gmail.readonlyconsole.cloud.google.comdevelopers.google.com/oauthplayground
Decision evidence
public snapshotAI called this Clean at 90.0% confidence as Benign with low false-positive risk.
Evidence for block
- package.json has postinstall running node -e fs.rmSync on specific better-sqlite3 build dirs then npm rebuild better-sqlite3
- dist/index.js uses child_process.execSync only for explicit --reset-config to run usrcp setup --adapter=gmail
- dist/index.js reads USRCP_PASSPHRASE and Gmail OAuth secrets from config for runtime polling
Evidence against
- No install-time writes to AI agent control surfaces, shell startup, VCS hooks, autostart, or broad home/project files found
- Runtime Gmail access is package-aligned: dist/reader.js uses gmail.readonly, users.messages.list/get, and filters sent mail
- dist/capture.js appends bounded message details to local usrcp ledger with idempotency keys, not external exfiltration code
- dist/config.js delegates encrypted adapter config storage to usrcp-adapter-kit for gmail-config.json
- No eval/vm/Function, remote code loading, native binary loading beyond dependency rebuild, or hidden endpoints found
Behavioral surface
ChildProcessCryptoEnvironmentVars
UrlStrings
Source & flagged code
2 flagged · loading sourcepackage.jsonView file
•scripts.postinstall = node -e "const fs=require(\"fs\"); for (const p of [\"node_modules/better-sqlite3/build\",\"node_modules/usrcp-core/node_modules/better-sqlite3/build\",\"node_modules/usrcp-stream/...
Critical
Red Install Lifecycle Script
Install-time lifecycle script matches a deterministic static-gate block pattern.
package.jsonView on unpkg•scripts.postinstall = node -e "const fs=require(\"fs\"); for (const p of [\"node_modules/better-sqlite3/build\",\"node_modules/usrcp-core/node_modules/better-sqlite3/build\",\"node_modules/usrcp-stream/...
High
Install Time Lifecycle Scripts
Package defines install-time lifecycle scripts.
package.jsonView on unpkgFindings
1 Critical1 High1 Medium2 Low
CriticalRed Install Lifecycle Scriptpackage.json
HighInstall Time Lifecycle Scriptspackage.json
MediumEnvironment Vars
LowScripts Present
LowUrl Strings