registry  /  switchroom  /  0.17.0

switchroom@0.17.0

Run Claude Code 24/7 on your Claude Pro/Max subscription over Telegram. Open-source alternative to OpenClaw and NanoClaw — no API keys.

AI Security Review

scanned 4h ago · by lpm-firewall-ai

No confirmed malicious install-time or import-time attack surface was found. Risky primitives are package-aligned runtime features for a Claude/Telegram agent orchestrator and require explicit user CLI actions.

Static reason
High-risk behavior combination matched malicious policy.; previous stored version diff introduced dangerous source
Trigger
User runs switchroom CLI commands such as setup, hostd install, or normal CLI invocation.
Impact
Can write switchroom/Claude agent config and start package-owned hostd containers when explicitly invoked; no unconsented npm lifecycle mutation found.
Mechanism
explicit agent orchestration, telemetry, vault, and hostd management commands
Rationale
Static inspection found broad agent-management capabilities, telemetry, Docker orchestration, and Claude config writes, but they are documented runtime commands with no npm install hook or hidden payload chain. Scanner claims about encrypted temp execution map to local vault materialization and package-aligned command logic rather than malware.
Evidence
package.jsondist/cli/switchroom.jstelegram-plugin/start.jstelegram-plugin/shared/bot-runtime.tsdist/vault/broker/server.jsvendor/hindsight-memory/tests/conftest.py~/.switchroom/analytics-id~/.switchroom/hostd/docker-compose.yml<agentDir>/.claude/.claude.json<agentDir>/telegram/.env<agentDir>/telegram/access.json
Network endpoints4
us.i.posthog.comghcr.io/switchroom/switchroom-hostdlogin.microsoftonline.com/commonlocalhost:8888/mcp/

Decision evidence

public snapshot
AI called this Clean at 84.0% confidence as Benign with medium false-positive risk.
Evidence for block
  • dist/cli/switchroom.js sends opt-out CLI telemetry to PostHog on command invocation.
  • dist/cli/switchroom.js has explicit user commands that write Claude agent config/trust and hostd compose files.
  • dist/cli/switchroom.js hostd install can run docker compose and pull ghcr.io/switchroom/switchroom-hostd.
Evidence against
  • package.json has no preinstall/install/postinstall hook; only prepublishOnly build/lint/test.
  • dist/cli/switchroom.js crypto/decrypt logic is local vault storage, not embedded payload execution.
  • telegram-plugin/start.js only imports bundled dist/server.js or local server.ts fallback.
  • telegram-plugin/shared/bot-runtime.ts uses execFileSync/spawnSync argv arrays for switchroom CLI calls, not shell eval.
  • vendor/hindsight-memory/tests/conftest.py is pytest fixture code, not a hidden executable payload.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShell
Supply chain
HighEntropyStringsTelemetryUrlStrings
ManifestNo manifest risk signals triggered.
scanned 718 file(s), 14.3 MB of source, external domains: 127.0.0.1, a.b, a.example, api.anthropic.com, api.example.com, api.github.com, api.linear.app, api.notion.com, api.openai.com, api.telegra.ph, api.telegram.org, b.example, bun.sh, claude.ai, claude.com, console.anthropic.com, docs.com, docs.google.com, docs.googleapis.com, drive.google.com, e.com, eu-assets.i.posthog.com, eu.i.posthog.com, ex.io, example.com, example.org, github.com, gitlab.com, hooks.slack.com, json-schema.org, linear.app, login.microsoftonline.com, media.giphy.com, microsoft.com, oauth2.googleapis.com, onedrive.live.com, posthog.com, quotes.toscrape.com, raw.githubusercontent.com, sentry.io, switchroom.ai, switchroom.dev, t.me, telegra.ph, u.co, us-assets.i.posthog.com, us.i.posthog.com, www.example.com, www.example.org, x.com
Oversized source lightweight scan
dist/cli/switchroom.js3.35 MB file, sampled 256 KB
FilesystemChildProcessEnvironmentVarsShellHighEntropyStringsUrlStringsgithub.com
telegram-plugin/dist/gateway/gateway.js2.66 MB file, sampled 256 KB
NetworkChildProcessEnvironmentVarsHighEntropyStringsUrlStringsapi.telegram.orgt.me

Source & flagged code

15 flagged · loading source
dist/host-control/main.jsView file
10429var EventEmitter2 = __require("node:events").EventEmitter; L10430: var childProcess = __require("node:child_process"); L10431: var path2 = __require("node:path");
High
Child Process

Package source references child process execution.

dist/host-control/main.jsView on unpkg · L10429
10875} L10876: const execArgv = process2.execArgv ?? []; L10877: if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) {
High
Shell

Package source references shell execution.

dist/host-control/main.jsView on unpkg · L10875
2457if (typeof node_buffer.Buffer === "function") { L2458: return node_buffer.Buffer.from(src, "base64"); L2459: } else if (typeof atob === "function") { ... L4916: yield* this.next(token); L4917: yield* this.end(forceDoc, endOffset); L4918: } L4919: *next(token) { L4920: if (node_process.env.LOG_STREAM) L4921: console.dir(token, { depth: null }); ... L7789: } L7790: if (process.platform === "win32") { L7791: const osRelease = os.release().split(".");
High
Sandbox Evasion Gated Capability

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

dist/host-control/main.jsView on unpkg · L2457
2457Cross-file remote execution chain: dist/host-control/main.js spawns dist/agent-scheduler/index.js; helper contains network access plus dynamic code execution. L2457: if (typeof node_buffer.Buffer === "function") { L2458: return node_buffer.Buffer.from(src, "base64"); L2459: } else if (typeof atob === "function") { ... L4916: yield* this.next(token); L4917: yield* this.end(forceDoc, endOffset); L4918: } L4919: *next(token) { L4920: if (node_process.env.LOG_STREAM) L4921: console.dir(token, { depth: null }); ... L7789: } L7790: if (process.platform === "win32") { L7791: const osRelease = os.release().split(".");
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/host-control/main.jsView on unpkg · L2457
telegram-plugin/dist/server.jsView file
12703sourceCode = this.opts.code.process(sourceCode, sch); L12704: const makeValidate = new Function(`${names_1.default.self}`, `${names_1.default.scope}`, sourceCode); L12705: const validate = makeValidate(this, this.scope.get());
Low
Eval

Package source references a known benign dynamic code generation pattern.

telegram-plugin/dist/server.jsView on unpkg · L12703
telegram-plugin/start.jsView file
25const target = existsSync(distPath) ? distPath : sourcePath; L26: await import(target);
Medium
Dynamic Require

Package source references dynamic require/import behavior.

telegram-plugin/start.jsView on unpkg · L25
telegram-plugin/shared/bot-runtime.tsView file
175contains invisible/control Unicode U+200B (zero width space) const safe = text.replace(/```/g, '`<U+200B>``')
Critical
Trojan Source Unicode

Source contains bidi control or invisible Unicode characters associated with Trojan Source attacks.

telegram-plugin/shared/bot-runtime.tsView on unpkg · L175
8* - `createRobustApiCall` — thin re-export of createRetryApiCall pre-wired L9: * with stderr logging (mirrors how gateway.ts constructs `robustApiCall`). L10: * - `makeSwitchroomExec` / `makeSwitchroomExecCombined` — factory fns for ... L26: import { run, type RunnerHandle } from '@grammyjs/runner' L27: import { execFileSync, spawnSync } from 'child_process' L28: import { createHash } from 'crypto' ... L116: const res = await prev(method, payload, signal) L117: process.stderr.write( L118: `tg-post method=${method} chat=${chat} thread=${thread} parse_mode=${parseMode} bytes=${bytes} hash=${hash} status=ok err=- code=- desc=-${tagSuffix}\n`, ... L203: export function makeSwitchroomExec(cfg: CliConfig = {}) { L204: const cli = cfg.cliPath ?? process.env.SWITCHROOM_CLI_PATH ?? 'switchroom' L205: const config = cfg.configPath ?? process.env.SWITCHROOM_CONFIG
Low
Weak Crypto

Package source references weak cryptographic algorithms.

telegram-plugin/shared/bot-runtime.tsView on unpkg · L8
dist/cli/switchroom.jsView file
context = nction renderProfileClaudeTemplate(profileName, profilesRoot = PROFILES_ROOT) {\n const profileDir = resolve4(profilesRoot, profileName);\n const hbsPath = join4(profileDir, "CLAUDE.md.hbs");\n const outPath = join4(profileDir, "CLAUDE.md");\n if (!existsSync6(hbsPath)) {\n return { wrote: false, path: outPath };\n }\n const source = readFileSync6(hbsPath, "utf-8");\n const template = import_handlebars.default.compile(source, { noEscape: true });\n const rendered = template({ profile: profileName });\n try {\n writeFileSync(outPath, rendered, "utf-8");\n return { wrote: true, path: outPath };\n } catch (err) {\n const code = err.code;\n if (code === "EACCES" || code === "EROFS" || code === "EPERM") {\n console.warn(`Note: profile CLAUDE.md at ${outPath} is not writable (${code}); ` + `skipping bookkeeping render. Agent scaffolds re-render the .hbs ` + `into their own dir, so this is non-fatal.`);\n return { wrote: false, path: outPath };\n }\n throw err;\n }\n}\nvar import_handlebars, PROFILES_ROOT, SHARE
Critical
Encrypted Payload Temp Execution

Source decrypts an embedded payload, writes it to disk, and executes it through a child process.

dist/cli/switchroom.jsView on unpkg
path = dist/cli/switchroom.js kind = oversized_source_file sizeBytes = 3510095 magicHex = [redacted]
High
Oversized Source File

Package contains source files above the static scanner size ceiling.

dist/cli/switchroom.jsView on unpkg
path = dist/cli/switchroom.js kind = oversized_cli_entrypoint sizeBytes = 3510095 magicHex = [redacted]
Medium
Oversized Cli Entrypoint

Package contains an oversized executable-looking CLI entrypoint.

dist/cli/switchroom.jsView on unpkg
bin/turn-pacing-hook.shView file
path = bin/turn-pacing-hook.sh kind = build_helper sizeBytes = 3963 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

bin/turn-pacing-hook.shView on unpkg
vendor/hindsight-memory/tests/conftest.pyView file
path = vendor/hindsight-memory/tests/conftest.py kind = payload_in_excluded_dir sizeBytes = 2548 magicHex = [redacted]
High
Payload In Excluded Dir

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

vendor/hindsight-memory/tests/conftest.pyView on unpkg
dist/vault/broker/server.jsView file
matchType = previous_version_dangerous_delta matchedPackage = switchroom@0.16.47 matchedIdentity = npm:c3dpdGNocm9vbQ:0.16.47 similarity = 0.883 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.

dist/vault/broker/server.jsView on unpkg
telegram-plugin/tests/secret-detect.test.tsView file
198patternName = private_key_rsa severity = critical line = 198 matchedText = const pe...----
Critical
Secret Pattern

RSA private key in telegram-plugin/tests/secret-detect.test.ts

telegram-plugin/tests/secret-detect.test.tsView on unpkg · L198

Findings

4 Critical6 High6 Medium8 Low
CriticalEncrypted Payload Temp Executiondist/cli/switchroom.js
CriticalTrojan Source Unicodetelegram-plugin/shared/bot-runtime.ts
CriticalPrevious Version Dangerous Deltadist/vault/broker/server.js
CriticalSecret Patterntelegram-plugin/tests/secret-detect.test.ts
HighChild Processdist/host-control/main.js
HighShelldist/host-control/main.js
HighSandbox Evasion Gated Capabilitydist/host-control/main.js
HighCross File Remote Execution Contextdist/host-control/main.js
HighPayload In Excluded Dirvendor/hindsight-memory/tests/conftest.py
HighOversized Source Filedist/cli/switchroom.js
MediumDynamic Requiretelegram-plugin/start.js
MediumNetwork
MediumEnvironment Vars
MediumShips Build Helperbin/turn-pacing-hook.sh
MediumOversized Cli Entrypointdist/cli/switchroom.js
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowEvaltelegram-plugin/dist/server.js
LowWeak Cryptotelegram-plugin/shared/bot-runtime.ts
LowFilesystem
LowHigh Entropy Strings
LowTelemetry
LowUrl Strings