registry  /  artor-cli  /  0.17.0

artor-cli@0.17.0

Artor CLI — version, publish, and preview your web prototypes.

AI Security Review

scanned 13m ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No confirmed malicious install-time behavior was found. The notable risk is explicit user-command setup/sync of Artor skills into local AI-agent skill locations.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs `artor skill sync`, `artor install-claude-plugin`, `artor install-skills`, registry/login/publish commands, or auto-update prompts.
Impact
Potential AI-agent extension lifecycle risk if a user/org intentionally syncs untrusted Artor skills; no unconsented npm lifecycle mutation or credential exfiltration was confirmed.
Mechanism
Authenticated Artor CLI operations, project packaging, explicit agent-skill installation/sync, and prompted/manual npm update flows.
Rationale
Static inspection does not support the scanner's malicious credential-exfiltration label; observed token use is normal bearer authentication to Artor endpoints and optional user-provided registry/GitHub credentials. Because the package includes explicit AI-agent skill installation/sync capability, warn rather than block.
Evidence
package.jsondist/index.jsREADME.md~/.artor/config.json.artor/project.json.artor/skills.lock.json.claude/skills/org/*AGENTS.md.npmrcartor-server.mjsnext.config.mjs
Network endpoints3
dash.artor.appregistry.npmjs.org/github.com/artorapp/skill/tree/main/artor

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/index.js:1387-1681 implements explicit `artor skill sync` that writes `.claude/skills/org/*` and `AGENTS.md`.
  • dist/index.js:6497-6654 implements explicit `artor install-claude-plugin`/`install-skills` that runs `claude` or `npx` installers.
  • dist/index.js:253 and 2016 write tokens/config to `~/.artor/config.json` and project `.npmrc` during login/registry commands.
Evidence against
  • package.json has no preinstall/install/postinstall lifecycle scripts; only `bin` points to `dist/index.js`.
  • dist/index.js network calls target Artor APIs (`https://dash.artor.app`) or npm/GitHub URLs and are tied to user-invoked CLI commands.
  • dist/index.js:1280-1307 excludes `.claude`, `.artor`, `.env`, `.npmrc`, credentials, keys, and similar secrets from packaged source uploads.
  • dist/index.js:8-34 redacts tokens/secrets in verbose logs instead of exposing them.
  • dist/index.js:581-600 validates spawned binary names/args before shelling out.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 1 file(s), 230 KB of source, external domains: claude.com, dash.artor.app, github.com, nodejs.org, registry.npmjs.org

Source & flagged code

3 flagged · loading source
dist/index.jsView file
36try { L37: return JSON.stringify(redactForLog(JSON.parse(body))); L38: } catch { ... L104: function registryUrl(pkg) { L105: return `https://registry.npmjs.org/${pkg.replace("/", "%2F")}/latest`; L106: } ... L123: try { L124: const raw = readFileSync(new URL("../package.json", import.meta.url), "utf8"); L125: return JSON.parse(raw); ... L150: const body = typeof init2.body === "string" ? redactBody(init2.body) : void 0; L151: process.stderr.write(`\x1B[2m\u2192 ${method} ${url}\x1B[0m L152: `);
Critical
Credential Exfiltration

Source appears to send environment or credential material to an external endpoint.

dist/index.jsView on unpkg · L36
36Trigger-reachable chain: manifest.bin -> dist/index.js L36: try { L37: return JSON.stringify(redactForLog(JSON.parse(body))); L38: } catch { ... L104: function registryUrl(pkg) { L105: return `https://registry.npmjs.org/${pkg.replace("/", "%2F")}/latest`; L106: } ... L123: try { L124: const raw = readFileSync(new URL("../package.json", import.meta.url), "utf8"); L125: return JSON.parse(raw); ... L150: const body = typeof init2.body === "string" ? redactBody(init2.body) : void 0; L151: process.stderr.write(`\x1B[2m\u2192 ${method} ${url}\x1B[0m L152: `);
Critical
Trigger Reachable Dangerous Capability

A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

dist/index.jsView on unpkg · L36
692L693: await import(pathToFileURL(resolve(here, ${JSON.stringify(spec.buildPath)})).href); L694: `;
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/index.jsView on unpkg · L692

Findings

2 Critical4 Medium5 Low
CriticalCredential Exfiltrationdist/index.js
CriticalTrigger Reachable Dangerous Capabilitydist/index.js
MediumDynamic Requiredist/index.js
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License