registry  /  artor-cli  /  0.15.0

artor-cli@0.15.0

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

AI Security Review

scanned 5d ago · by lpm-firewall-ai

Review flagged AI-agent configuration or capability changes. This remains warn-only unless evidence shows foreign-agent hijack through preinstall/install/postinstall, hidden persistence, exfiltration, remote code execution, or other concrete malicious behavior.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs `artor skill sync`, `artor install`, `artor install-skills`, `artor install-claude-plugin`, `artor registry add/login`, or publish/init commands.
Impact
Can write project `.claude/skills/org/`, `AGENTS.md`, `.artor/*`, `.npmrc`, downloaded project/template files, and send user-supplied credentials to Artor API; no unconsented lifecycle mutation observed.
Mechanism
authenticated Artor CLI network operations and user-invoked agent skill/plugin installation
Policy narrative
The package is a broad Artor CLI. Risky behavior is reachable through explicit commands: authenticated API calls, packaging/publishing local projects with secret exclusions, writing local project config, syncing org skills into Claude's project skill directory, updating AGENTS.md, and launching external CLIs for Artor skill/plugin installation. I found no npm lifecycle execution, automatic import-time mutation, credential harvesting beyond user-supplied/authenticated CLI flows, or exfiltration to non-Artor endpoints.
Rationale
Source inspection does not support a malicious verdict: the network and credential paths are package-aligned, user-invoked CLI functionality, with no lifecycle hook or automatic foreign agent control-surface mutation. Because it can intentionally write Claude/agent skill surfaces from remote Artor-managed content, warn rather than block.
Evidence
package.jsondist/index.jsREADME.md~/.artor/config.json.artor/project.json.artor/skills.lock.json.claude/skills/org/<skill>/AGENTS.md.npmrcartor-server.mjsnext.config.mjs
Network endpoints5
dash.artor.appregistry.npmjs.org/github.com/artorapp/skill/tree/main/artorclaude.com/codenodejs.org

Decision evidence

public snapshot
AI called this Suspicious at 82.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • User-invoked `artor skill sync` downloads skill tarballs from Artor API and writes `.claude/skills/org/<name>/` plus an `AGENTS.md` managed block in `dist/index.js`.
  • User-invoked `artor install` can run `claude plugin marketplace add artorapp/skill`, `claude plugin install artor@artor`, or `npx -y skills@latest add https://github.com/artorapp/skill/tree/main/artor`.
  • `registry add` and `skill add` can send user-supplied/env credentials to package-aligned Artor API endpoints.
  • `maybeOfferGlobalInstall` may prompt interactive npx/local users to run `npm install -g artor-cli@latest`.
Evidence against
  • `package.json` has no install/postinstall lifecycle hook; `prepack` is publish-time only.
  • `dist/index.js` command dispatch requires explicit CLI subcommands; agent/plugin writes are not install-time behavior.
  • Verbose API logging redacts authorization, token, password, secret, credential, cookie, and token-like values.
  • Publish packaging excludes `.env*`, `.npmrc`, `.ssh`, `.claude`, `.artor`, cloud credential names, private keys, and escaping symlinks.
  • Child process helper validates binary and argument characters before spawning.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 1 file(s), 204 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 { ... L127: try { L128: const raw = readFileSync(new URL("../package.json", import.meta.url), "utf8"); L129: return JSON.parse(raw); ... L154: const body = typeof init2.body === "string" ? redactBody(init2.body) : void 0; L155: process.stderr.write(`\x1B[2m\u2192 ${method} ${url}\x1B[0m L156: `); ... L205: try { L206: res = await fetch(url, { ...init2, headers }); L207: } catch {
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 { ... L127: try { L128: const raw = readFileSync(new URL("../package.json", import.meta.url), "utf8"); L129: return JSON.parse(raw); ... L154: const body = typeof init2.body === "string" ? redactBody(init2.body) : void 0; L155: process.stderr.write(`\x1B[2m\u2192 ${method} ${url}\x1B[0m L156: `); ... L205: try { L206: res = await fetch(url, { ...init2, headers }); L207: } catch {
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
659L660: await import(pathToFileURL(resolve(here, ${JSON.stringify(spec.buildPath)})).href); L661: `;
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/index.jsView on unpkg · L659

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