registry  /  shellular  /  0.0.39

shellular@0.0.39

Shellular CLI — host your dev environment for remote access from your phone.

AI Security Review

scanned 10d ago · by lpm-firewall-ai

This is a remote development host CLI with broad, advertised dual-use access after pairing. The main unresolved risk is silent runtime mutation of Claude hook settings for status notifications, plus powerful remote terminal/filesystem/agent features.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs shellular or shellular start and pairs/approves a client.
Impact
Approved clients can read/write workspace files, open shells, proxy localhost, manage ports, launch AI agents, and request daemon self-update.
Mechanism
E2EE WebSocket relay controlling local dev capabilities
Attack narrative
Running the CLI creates local Shellular state, registers the host with the Shellular relay, opens an encrypted WebSocket, and after pairing/approval lets a remote client operate terminal, filesystem, proxy, port, and AI-agent functions within the configured workspace. It also installs a helper and adds Claude hooks at runtime for session notifications. These are powerful and somewhat invasive, but they match the package’s documented remote-development purpose and are not install-time or hidden payload behavior.
Rationale
Static source inspection confirms a high-risk remote access tool, but the capabilities are documented, user-invoked, paired/approved by default, and no concrete malicious payload or exfiltration outside the product design was found. The silent AI-agent hook registration is worth warning on rather than blocking absent evidence of control hijack or covert execution.
Evidence
package.jsonreadme.mddist/main.js~/.shellular/config.json~/.shellular/logs~/.shellular/clients.json~/.shellular/hooks/shellular-notify.mjs~/.shellular/notify~/.claude/settings.jsonconfigured --dir workspace
Network endpoints7
wss://api.shellular.devregistry.npmjs.org/shellularshellular.devopencode.ai/installclaude.ai/install.shclaude.ai/install.ps1cursor.com/install

Decision evidence

public snapshot
AI called this Suspicious at 78.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/main.js registers with default relay wss://api.shellular.dev and exposes terminal, filesystem, proxy, ports, and AI-agent controls to approved clients.
  • dist/main.js writes ~/.claude/settings.json hooks and ~/.shellular/hooks/shellular-notify.mjs at runtime to observe Claude/Codex session events.
  • dist/main.js can spawn PTYs, agent CLIs, pm2 daemons, self-update commands, and kill processes by port after client messages.
Evidence against
  • package.json has no install/preinstall/postinstall lifecycle hooks; main/bin are user-invoked CLI entrypoints.
  • readme.md clearly describes remote terminal, filesystem, proxy, ports, agents, E2EE, QR pairing, and client approval behavior.
  • dist/main.js restricts filesystem operations to the configured --dir root and requires client approval by default for unknown clients.
  • No confirmed fetch-decode-eval chain or dynamic remote payload execution was found; scanner likely matched git show/base64/update logic and normal CLI spawning.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsUrlStrings
Manifest
CopyleftLicense
scanned 2 file(s), 591 KB of source, external domains: claude.ai, cursor.com, gh.io, opencode.ai, raw.githubusercontent.com, registry.npmjs.org

Source & flagged code

5 flagged · loading source
dist/main.jsView file
26L27: // package.json L28: var package_default = { ... L37: prepublishOnly: "pnpm run build", L38: "ci:publish": "pnpm publish --access public", L39: "try-run": "pnpm run build && node dist/main.js" ... L127: // src/utils.ts L128: import { spawnSync } from "child_process"; L129: import fs from "fs"; ... L147: } L148: const shell2 = process2.env.SHELL || "/bin/sh"; L149: const result = spawnSync(shell2, ["-lc", `which ${command}`], {
Critical
Remote Asset Decode Execute

Source fetches a remote non-code asset, decodes its contents, and dynamically executes the decoded payload.

dist/main.jsView on unpkg · L26
Trigger-reachable chain: manifest.main -> dist/main.js Reachable file contains a blocking source-risk pattern.
Critical
Trigger Reachable Dangerous Capability

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

dist/main.jsView on unpkg
127// src/utils.ts L128: import { spawnSync } from "child_process"; L129: import fs from "fs";
High
Child Process

Package source references child process execution.

dist/main.jsView on unpkg · L127
407}, L408: PowerShell: { L409: os: ["windows"],
High
Shell

Package source references shell execution.

dist/main.jsView on unpkg · L407
26L27: // package.json L28: var package_default = { ... L37: prepublishOnly: "pnpm run build", L38: "ci:publish": "pnpm publish --access public", L39: "try-run": "pnpm run build && node dist/main.js" ... L127: // src/utils.ts L128: import { spawnSync } from "child_process"; L129: import fs from "fs"; ... L147: } L148: const shell2 = process2.env.SHELL || "/bin/sh"; L149: const result = spawnSync(shell2, ["-lc", `which ${command}`], {
Low
Weak Crypto

Package source references weak cryptographic algorithms.

dist/main.jsView on unpkg · L26

Findings

2 Critical2 High3 Medium6 Low
CriticalRemote Asset Decode Executedist/main.js
CriticalTrigger Reachable Dangerous Capabilitydist/main.js
HighChild Processdist/main.js
HighShelldist/main.js
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowWeak Cryptodist/main.js
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowCopyleft License