registry  /  @rubytech/create-sitedesk-code  /  0.1.378

@rubytech/create-sitedesk-code@0.1.378

Install SiteDesk — automated back office for independent building contractors

AI Security Review

scanned 12d ago · by lpm-firewall-ai

LPM blocks this version under the AI-agent control-surface policy. The package is a CLI installer that mutates the local Claude Code control surface. It forces bypassPermissions and installs/registers plugins and agents under the brand-scoped Claude config.

Static reason
High-risk behavior combination matched malicious policy.; source matched previously finalized malicious package; routed for review
Trigger
User runs the create-sitedesk-code bin.
Impact
Claude sessions for the installed brand can run with permission checks bypassed and expanded trusted token-provisioning behavior, enabling unconsented agent control-surface weakening.
Mechanism
AI-agent permission bypass and plugin/agent registration during installer run
Policy narrative
Running the bin performs a broad privileged installer, then creates a brand-scoped Claude config and writes settings that set defaultMode to bypassPermissions. It also registers marketplaces/plugins and symlinks bundled agents into Claude's agent resolution path. This is an unconsented weakening of an AI agent permission boundary packaged as an installer, even though many network and system actions are aligned with the product setup.
Rationale
Direct inspection confirms concrete AI-agent control-surface mutation: the installer writes Claude settings that bypass permission checks and expands trusted token-provisioning behavior. The absence of npm install-time hooks reduces stealth, but the runtime bin still performs the dangerous mutation when invoked. Product guard normalized a concrete AI-agent control hijack publish_block to the blockable dangerous-capability shape.
Evidence
package.jsondist/index.jsdist/permissions-seed.jsdist/specialist-registration.jsdist/lib/plugin-install.jspayload/platform/config/brand.json~/.sitedesk-code/.claude/settings.json~/.sitedesk-code/.claude/.claude.json~/.sitedesk-code/.claude/agents/*.md~/sitedesk-code~/sitedesk-code/platform~/sitedesk-code/server~/sitedesk-code/premium-plugins
Network endpoints12
registry.npmjs.orggithub.comregistry.npmjs.org/dl.google.com/linux/linux_signing_key.pubdl.google.com/linux/chrome/deb/deb.nodesource.com/setup_22.xdebian.neo4j.com/neotechnology.gpg.keyollama.ai/install.shastral.sh/uv/install.shgithub.com/cloudflare/cloudflared/releases/download/2026.6.0/cloudflared-linux-arm64.debgithub.com/cloudflare/cloudflared/releases/download/2026.6.0/cloudflared-linux-amd64.debgithub.com/ggerganov/whisper.cpp.git

Decision evidence

public snapshot
AI called this Malicious at 90.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for policy block
  • dist/index.js bin executes a full installer with sudo/system mutation, remote installs, and payload deployment when user runs create-sitedesk-code.
  • dist/permissions-seed.js writes CLAUDE_CONFIG_DIR/settings.json with permissions.defaultMode=bypassPermissions.
  • dist/permissions-seed.js seeds autoMode rules explicitly allowing Cloudflare token minting and persistence to account secrets.
  • dist/index.js registers Claude plugin marketplaces, installs plugins, and symlinks bundled agents into CLAUDE_CONFIG_DIR/agents.
  • dist/index.js downloads and executes installer scripts via curl pipes for NodeSource, Ollama, uv, and apt signing keys.
Evidence against
  • package.json has no install/postinstall lifecycle hook; prepublishOnly is publish-time only.
  • Network hosts largely match installer purpose: npm, GitHub, Anthropic Claude plugins, Cloudflare, Neo4j, Ollama, NodeSource, Google Chrome, Astral uv.
  • No source evidence of credential exfiltration to an attacker-specific endpoint was found.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNativeBindingsNetworkShell
Supply chain
HighEntropyStringsMinifiedObfuscatedTelemetryUrlStrings
Manifest
NoLicense
scanned 653 file(s), 9.74 MB of source, external domains: 0.0.0.0, 127.0.0.1, api.anthropic.com, api.joblogic.com, api.replicate.com, api.telegram.org, appcenter.intuit.com, astral.sh, brew.sh, chevrotain.io, claude.ai, deb.nodesource.com, debian.neo4j.com, dl.google.com, docs.getmaxy.com, docs.realagent.network, en.wikipedia.org, fonts.googleapis.com, fonts.gstatic.com, getmaxy.com, github.com, graph.microsoft.com, identityserver.joblogic.com, langium.org, llmstxt.org, login.microsoftonline.com, maxy.bot, maxy.setup, oauth.platform.intuit.com, ollama.ai, one.dash.cloudflare.com, platform.claude.com, player.vimeo.com, quickbooks.api.intuit.com, react.dev, registry.npmjs.org, sandbox-quickbooks.api.intuit.com, schema.org, uatapi.joblogic.com, uatidentityserver.joblogic.com, www.linkedin.com, www.w3.org, www.youtube-nocookie.com

Source & flagged code

24 flagged · loading source
payload/platform/scripts/smoke-boot-services.shView file
317patternName = generic_password severity = medium line = 317 matchedText = local ne...:-}"
Medium
Secret Pattern

Package contains a possible secret pattern.

payload/platform/scripts/smoke-boot-services.shView on unpkg · L317
dist/index.jsView file
134for (const host of ["registry.npmjs.org", "github.com"]) { L135: const dns = spawnSync("host", ["-W", "5", host], { encoding: "utf-8", stdio: "pipe", timeout: 10_000 }); L136: logFile(`DNS ${host}: ${dns.status === 0 ? "OK" : "FAIL"} — ${(dns.stdout || dns.stderr || "").trim().split("\n")[0]}`); ... L141: "--connect-timeout", "10", L142: "https://registry.npmjs.org/", L143: ], { encoding: "utf-8", stdio: "pipe", timeout: 15_000 }); ... L148: function captureNpmDebugLog() { L149: const logsDir = resolve(process.env.HOME ?? "/root", ".npm/_logs"); L150: if (!existsSync(logsDir))
Critical
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution with blocking evidence.

dist/index.jsView on unpkg · L134
1#!/usr/bin/env node L2: import { execFileSync, spawn, spawnSync } from "node:child_process"; L3: import { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync, rmSync, readdirSync, appendFileSync, openSync, closeSync, chmodSync, statSync, realpathSync } from "node:fs"; ... L9: import { buildHeartbeatCronBlock, mergeHeartbeatBlock } from "./cron-registration.js"; L10: import { validateTierFlag, validateEntitlementBase64, applyTierToAccountConfig, entitlementPath } from "./tier-flag.js"; L11: import { parseOsRelease, isUbuntuLike as isUbuntuLikePure, parseAptCacheCandidate, decideAptResolution, } from "./apt-resolve.js"; ... L44: } L45: const INSTALL_DIR = resolve(process.env.HOME ?? "/root", BRAND.installDir); L46: const PERSIST_DIR = resolve(process.env.HOME ?? "/root", BRAND.configDir); ... L100: ` ${BRAND.productName} Install Log — ${new Date().toISOString()}`, L101: ` Node ${process.version} | ${process.platform} ${process.arch}`, L102: "=".repeat(64),
Critical
Download Execute

Source downloads or fetches remote code and executes it.

dist/index.jsView on unpkg · L1
1Trigger-reachable chain: manifest.bin -> dist/index.js L1: #!/usr/bin/env node L2: import { execFileSync, spawn, spawnSync } from "node:child_process"; L3: import { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync, rmSync, readdirSync, appendFileSync, openSync, closeSync, chmodSync, statSync, realpathSync } from "node:fs"; ... L9: import { buildHeartbeatCronBlock, mergeHeartbeatBlock } from "./cron-registration.js"; L10: import { validateTierFlag, validateEntitlementBase64, applyTierToAccountConfig, entitlementPath } from "./tier-flag.js"; L11: import { parseOsRelease, isUbuntuLike as isUbuntuLikePure, parseAptCacheCandidate, decideAptResolution, } from "./apt-resolve.js"; ... L44: } L45: const INSTALL_DIR = resolve(process.env.HOME ?? "/root", BRAND.installDir); L46: const PERSIST_DIR = resolve(process.env.HOME ?? "/root", BRAND.configDir); ... L100: ` ${BRAND.productName} Install Log — ${new Date().toISOString()}`, L101: ` Node ${process.version} | ${process.platform} ${process.arch}`, L102: "=".repeat(64),
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 · L1
1#!/usr/bin/env node L2: import { execFileSync, spawn, spawnSync } from "node:child_process"; L3: import { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync, rmSync, readdirSync, appendFileSync, openSync, closeSync, chmodSync, statSync, realpathSync } from "node:fs";
High
Child Process

Package source references child process execution.

dist/index.jsView on unpkg · L1
506// Fetch + dearmor the signing key, write to /etc/apt/trusted.gpg.d/. Pipe L507: // composition runs through bash -c so the curl|gpg pipeline is one L508: // privileged command rather than two separate sudo escalations.
High
Shell

Package source references shell execution.

dist/index.jsView on unpkg · L506
1#!/usr/bin/env node L2: import { execFileSync, spawn, spawnSync } from "node:child_process"; L3: import { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync, rmSync, readdirSync, appendFileSync, openSync, closeSync, chmodSync, statSync, realpathSync } from "node:fs"; ... L9: import { buildHeartbeatCronBlock, mergeHeartbeatBlock } from "./cron-registration.js"; L10: import { validateTierFlag, validateEntitlementBase64, applyTierToAccountConfig, entitlementPath } from "./tier-flag.js"; L11: import { parseOsRelease, isUbuntuLike as isUbuntuLikePure, parseAptCacheCandidate, decideAptResolution, } from "./apt-resolve.js"; ... L44: } L45: const INSTALL_DIR = resolve(process.env.HOME ?? "/root", BRAND.installDir); L46: const PERSIST_DIR = resolve(process.env.HOME ?? "/root", BRAND.configDir); ... L100: ` ${BRAND.productName} Install Log — ${new Date().toISOString()}`, L101: ` Node ${process.version} | ${process.platform} ${process.arch}`, L102: "=".repeat(64),
High
Sandbox Evasion Gated Capability

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

dist/index.jsView on unpkg · L1
1Cross-file remote execution chain: dist/index.js spawns payload/platform/scripts/wifi-provision-server/server.js; helper contains network access plus dynamic code execution. L1: #!/usr/bin/env node L2: import { execFileSync, spawn, spawnSync } from "node:child_process"; L3: import { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync, rmSync, readdirSync, appendFileSync, openSync, closeSync, chmodSync, statSync, realpathSync } from "node:fs"; ... L9: import { buildHeartbeatCronBlock, mergeHeartbeatBlock } from "./cron-registration.js"; L10: import { validateTierFlag, validateEntitlementBase64, applyTierToAccountConfig, entitlementPath } from "./tier-flag.js"; L11: import { parseOsRelease, isUbuntuLike as isUbuntuLikePure, parseAptCacheCandidate, decideAptResolution, } from "./apt-resolve.js"; ... L44: } L45: const INSTALL_DIR = resolve(process.env.HOME ?? "/root", BRAND.installDir); L46: const PERSIST_DIR = resolve(process.env.HOME ?? "/root", BRAND.configDir); ... L100: ` ${BRAND.productName} Install Log — ${new Date().toISOString()}`, L101: ` Node ${process.version} | ${process.platform} ${process.arch}`, L102: "=".repeat(64),
High
Cross File Remote Execution Context

Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.

dist/index.jsView on unpkg · L1
1066console.log(" This may take 15–30 minutes on Raspberry Pi..."); L1067: console.log(" [privileged] npm install -g @anthropic-ai/claude-code@latest"); L1068: shellRetry("npm", ["install", "-g", ...NPM_NET_FLAGS, "--loglevel", "verbose", "@anthropic-ai/claude-code@latest"], { sudo: true, timeout: 2_400_000 }, // 40 min — Pi downloads can... ... L1081: logFile(`[install-permissions] action=${permissionsSeed.action} autoMode=${permissionsSeed.autoMode} path=${permissionsSeed.path}`); L1082: const marketplaceList = spawnSync("claude", ["plugin", "marketplace", "list"], { stdio: "pipe", encoding: "utf-8", env: claudePluginEnv() }); L1083: if (marketplaceList.stderr)
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/index.jsView on unpkg · L1066
1#!/usr/bin/env node L2: import { execFileSync, spawn, spawnSync } from "node:child_process"; L3: import { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync, rmSync, readdirSync, appendFileSync, openSync, closeSync, chmodSync, statSync, realpathSync } from "node:fs"; ... L9: import { buildHeartbeatCronBlock, mergeHeartbeatBlock } from "./cron-registration.js"; L10: import { validateTierFlag, validateEntitlementBase64, applyTierToAccountConfig, entitlementPath } from "./tier-flag.js"; L11: import { parseOsRelease, isUbuntuLike as isUbuntuLikePure, parseAptCacheCandidate, decideAptResolution, } from "./apt-resolve.js"; ... L44: } L45: const INSTALL_DIR = resolve(process.env.HOME ?? "/root", BRAND.installDir); L46: const PERSIST_DIR = resolve(process.env.HOME ?? "/root", BRAND.configDir); ... L100: ` ${BRAND.productName} Install Log — ${new Date().toISOString()}`, L101: ` Node ${process.version} | ${process.platform} ${process.arch}`, L102: "=".repeat(64),
Medium
Install Persistence

Source writes installer persistence such as shell profile or service configuration.

dist/index.jsView on unpkg · L1
payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/__tests__/restatement-ladder.test.shView file
path = payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/__tests__/restatement-ladder.test.sh kind = payload_in_excluded_dir sizeBytes = 936 magicHex = [redacted]
High
Payload In Excluded Dir

Package hides binary, compressed, or executable-looking payloads in test/fixture/hidden paths.

payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/__tests__/restatement-ladder.test.shView on unpkg
path = payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/__tests__/restatement-ladder.test.sh kind = build_helper sizeBytes = 936 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/__tests__/restatement-ladder.test.shView on unpkg
payload/server/public/assets/cormorant-latin-ext-500-normal-AH9qog1s.woff2View file
path = [redacted]-latin-ext-500-normal-AH9qog1s.woff2 kind = high_entropy_blob sizeBytes = 19620 magicHex = [redacted]
High
Ships High Entropy Blob

Package ships high-entropy non-source blobs.

payload/server/public/assets/cormorant-latin-ext-500-normal-AH9qog1s.woff2View on unpkg
payload/platform/lib/graph-mcp/dist/index.jsView file
matchType = normalized_sha256 matchedPackage = @rubytech/create-sitedesk-code@0.1.386 matchedPath = payload/platform/lib/graph-mcp/dist/index.js matchedIdentity = npm:[redacted]:0.1.386 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

payload/platform/lib/graph-mcp/dist/index.jsView on unpkg
payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.jsView file
matchType = normalized_sha256 matchedPackage = @rubytech/create-sitedesk-code@0.1.386 matchedPath = [redacted].js matchedIdentity = npm:[redacted]:0.1.386 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.jsView on unpkg
payload/platform/lib/anthropic-key/dist/index.jsView file
matchType = normalized_sha256 matchedPackage = @rubytech/create-sitedesk-code@0.1.386 matchedPath = payload/platform/lib/anthropic-key/dist/index.js matchedIdentity = npm:[redacted]:0.1.386 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

payload/platform/lib/anthropic-key/dist/index.jsView on unpkg
payload/platform/plugins/admin/lib/mcp-spawn-tee/index.jsView file
matchType = normalized_sha256 matchedPackage = @rubytech/create-sitedesk-code@0.1.386 matchedPath = [redacted]-spawn-tee/index.js matchedIdentity = npm:[redacted]:0.1.386 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

payload/platform/plugins/admin/lib/mcp-spawn-tee/index.jsView on unpkg
payload/platform/plugins/aeo/lib/mcp-spawn-tee/index.jsView file
matchType = normalized_sha256 matchedPackage = @rubytech/create-sitedesk-code@0.1.386 matchedPath = [redacted]-spawn-tee/index.js matchedIdentity = npm:[redacted]:0.1.386 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

payload/platform/plugins/aeo/lib/mcp-spawn-tee/index.jsView on unpkg
payload/platform/plugins/email/mcp/dist/__tests__/email-delete.test.jsView file
52patternName = generic_password severity = medium line = 52 matchedText = credenti..." },
Medium
Secret Pattern

Hardcoded password in payload/platform/plugins/email/mcp/dist/__tests__/email-delete.test.js

payload/platform/plugins/email/mcp/dist/__tests__/email-delete.test.jsView on unpkg · L52
payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.jsView file
28patternName = generic_password severity = medium line = 28 matchedText = password...nt",
Medium
Secret Pattern

Hardcoded password in payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js

payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.jsView on unpkg · L28
43patternName = generic_password severity = medium line = 43 matchedText = password...nt",
Medium
Secret Pattern

Hardcoded password in payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js

payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.jsView on unpkg · L43
57patternName = generic_password severity = medium line = 57 matchedText = password...nt",
Medium
Secret Pattern

Hardcoded password in payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js

payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.jsView on unpkg · L57
127patternName = generic_password severity = medium line = 127 matchedText = email: "...0*",
Medium
Secret Pattern

Hardcoded password in payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js

payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.jsView on unpkg · L127
payload/platform/lib/task-secrets/src/__tests__/redact-secrets.test.tsView file
73patternName = generic_password severity = medium line = 73 matchedText = { passwo...' },
Medium
Secret Pattern

Hardcoded password in payload/platform/lib/task-secrets/src/__tests__/redact-secrets.test.ts

payload/platform/lib/task-secrets/src/__tests__/redact-secrets.test.tsView on unpkg · L73

Findings

3 Critical12 High13 Medium8 Low
CriticalSame File Env Network Executiondist/index.js
CriticalDownload Executedist/index.js
CriticalTrigger Reachable Dangerous Capabilitydist/index.js
HighChild Processdist/index.js
HighShelldist/index.js
HighSandbox Evasion Gated Capabilitydist/index.js
HighCross File Remote Execution Contextdist/index.js
HighRuntime Package Installdist/index.js
HighShips High Entropy Blobpayload/server/public/assets/cormorant-latin-ext-500-normal-AH9qog1s.woff2
HighPayload In Excluded Dirpayload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/__tests__/restatement-ladder.test.sh
HighKnown Malware Source Similaritypayload/platform/lib/graph-mcp/dist/index.js
HighKnown Malware Source Similaritypayload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js
HighKnown Malware Source Similaritypayload/platform/lib/anthropic-key/dist/index.js
HighKnown Malware Source Similaritypayload/platform/plugins/admin/lib/mcp-spawn-tee/index.js
HighKnown Malware Source Similaritypayload/platform/plugins/aeo/lib/mcp-spawn-tee/index.js
MediumSecret Patternpayload/platform/scripts/smoke-boot-services.sh
MediumDynamic Require
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/index.js
MediumShips Build Helperpayload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/__tests__/restatement-ladder.test.sh
MediumStructural Risk Force Deep Review
MediumSecret Patternpayload/platform/plugins/email/mcp/dist/__tests__/email-delete.test.js
MediumSecret Patternpayload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js
MediumSecret Patternpayload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js
MediumSecret Patternpayload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js
MediumSecret Patternpayload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js
MediumSecret Patternpayload/platform/lib/task-secrets/src/__tests__/redact-secrets.test.ts
LowNon Install Lifecycle Scripts
LowScripts Present
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowTelemetry
LowUrl Strings
LowNo License