registry  /  @storybook/cli  /  10.5.0

@storybook/cli@10.5.0

Storybook CLI: Develop, document, and test UI components in isolation

AI Security Review

scanned 3h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. The notable risk is a guarded Storybook automigration that detects AI-agent context and can add @storybook/addon-mcp to the user's Storybook project. This is explicit CLI migration behavior, not npm install-time compromise.

Static reason
One or more suspicious static signals were detected.
Trigger
User runs storybook upgrade or storybook automigrate, especially with --yes or accepted prompts
Impact
May modify project Storybook config/dependencies to include @storybook/addon-mcp; no hidden lifecycle execution or exfiltration confirmed
Mechanism
first-party Storybook MCP addon setup during automigration
Rationale
Static inspection does not support a malicious verdict: suspicious execution, install, env, and file-write primitives are part of the user-invoked Storybook CLI. The agent-detected MCP addon automigration is real first-party agent extension setup, so a warn-level suspicious verdict is more appropriate than clean or block.
Evidence
package.jsondist/bin/index.jsdist/_node-chunks/run-UOXW6XFP.jsdist/_node-chunks/chunk-Z7PVZEPZ.js
Network endpoints3
github.com/storybookjs/mcpstorybook.js.org/docs/releases/migration-guide?ref=upgradegithub.com/storybookjs/storybook.git

Decision evidence

public snapshot
AI called this Suspicious at 84.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/_node-chunks/run-UOXW6XFP.js has an automigration fix addon-mcp that calls detectAgent() and proposes @storybook/addon-mcp.
  • addon-mcp run() invokes add('@storybook/addon-mcp') with yes:true, skipInstall:true, skipPostinstall:true when the migration is accepted or --yes is used.
  • CLI commands perform package-manager installs and project file rewrites for init/add/upgrade/automigrate workflows.
Evidence against
  • package.json has no preinstall/install/postinstall/prepare lifecycle scripts.
  • dist/bin/index.js only checks Node version then imports the CLI dispatcher; no install-time execution.
  • The MCP behavior is Storybook-owned and tied to explicit upgrade/automigrate flow, not hidden npm lifecycle mutation of a foreign agent surface.
  • No credential harvesting, destructive action, stealth persistence, or exfiltration endpoint was found in inspected package files.
  • Network URLs found are Storybook/GitHub docs, telemetry imports, and sandbox/template helper references aligned with CLI features.
Behavioral surface
Source
ChildProcessDynamicRequireEnvironmentVarsFilesystemShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 14 file(s), 804 KB of source, external domains: angular.dev, discord.gg, git-scm.com, github.com, nextjs.org, storybook.js.org

Source & flagged code

6 flagged · loading source
dist/_node-chunks/chunk-Z7PVZEPZ.jsView file
4157import { promisify } from "node:util"; L4158: import { execFile as execFileCallback, execFileSync as execFileSyncOriginal } from "node:child_process"; L4159: import { fileURLToPath } from "node:url";
High
Child Process

Package source references child process execution.

dist/_node-chunks/chunk-Z7PVZEPZ.jsView on unpkg · L4157
dist/_node-chunks/run-UOXW6XFP.jsView file
243})) : i.isMacOS && typeof t13 == "string" && t13 ? i.getDarwinApplicationVersion(t13) : i.isWindows && typeof n3 == "string" && n3 ? i.windowsExeExists(n3).then((function(e4) { L244: return r2 = e4, e4 ? i.run(`powershell "& '${e4}' -v | Write-Output"`).then((function(e5) { L245: return i.findVersion(e5);
High
Shell

Package source references shell execution.

dist/_node-chunks/run-UOXW6XFP.jsView on unpkg · L243
5var __filename = CJS_COMPAT_NODE_URL_vp9iaavr9ps.fileURLToPath(import.meta.url); L6: var __dirname = CJS_COMPAT_NODE_PATH_vp9iaavr9ps.dirname(__filename); L7: var require = CJS_COMPAT_NODE_MODULE_vp9iaavr9ps.createRequire(import.meta.url); ... L51: (t13 = t13 || {}).clipboard && console.log(` L52: *** Clipboard option removed - use clipboardy or clipboard-cli directly *** L53: `); ... L68: var r2 = !1; L69: process.stdout.isTTY && (r2 = !0), console.log(n5(e5, Object.assign({}, t14, { console: r2 }))); L70: } ... L81: if (e3.all) return a(Object.assign({}, i.defaults, { npmPackages: !0, npm[redacted]: !0, pnpmGlobalPackages: !0 }), e3); L82: if (e3.raw) return a(JSON.parse(e3.raw), e3); L83: if (e3.helper) {
High
Sandbox Evasion Gated Capability

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

dist/_node-chunks/run-UOXW6XFP.jsView on unpkg · L5
5Cross-file remote execution chain: dist/_node-chunks/run-UOXW6XFP.js spawns dist/_node-chunks/chunk-Z7PVZEPZ.js; helper contains network access plus dynamic code execution. L5: var __filename = CJS_COMPAT_NODE_URL_vp9iaavr9ps.fileURLToPath(import.meta.url); L6: var __dirname = CJS_COMPAT_NODE_PATH_vp9iaavr9ps.dirname(__filename); L7: var require = CJS_COMPAT_NODE_MODULE_vp9iaavr9ps.createRequire(import.meta.url); ... L51: (t13 = t13 || {}).clipboard && console.log(` L52: *** Clipboard option removed - use clipboardy or clipboard-cli directly *** L53: `); ... L68: var r2 = !1; L69: process.stdout.isTTY && (r2 = !0), console.log(n5(e5, Object.assign({}, t14, { console: r2 }))); L70: } ... L81: if (e3.all) return a(Object.assign({}, i.defaults, { npmPackages: !0, npm[redacted]: !0, pnpmGlobalPackages: !0 }), e3); L82: if (e3.raw) return a(JSON.parse(e3.raw), e3); L83: if (e3.helper) {
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/_node-chunks/run-UOXW6XFP.jsView on unpkg · L5
5019} catch { L5020: let result = spawnSync( L5021: process.execPath, ... L5031: logger27.warn( L5032: `Could not resolve the postinstall hook of ${addonName}, skipping its configuration. Run \`npx storybook add ${addonName}\` to set it up manually.` L5033: );
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/_node-chunks/run-UOXW6XFP.jsView on unpkg · L5019
6var __dirname = CJS_COMPAT_NODE_PATH_vp9iaavr9ps.dirname(__filename); L7: var require = CJS_COMPAT_NODE_MODULE_vp9iaavr9ps.createRequire(import.meta.url); L8:
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/_node-chunks/run-UOXW6XFP.jsView on unpkg · L6

Findings

5 High3 Medium3 Low
HighChild Processdist/_node-chunks/chunk-Z7PVZEPZ.js
HighShelldist/_node-chunks/run-UOXW6XFP.js
HighSandbox Evasion Gated Capabilitydist/_node-chunks/run-UOXW6XFP.js
HighCross File Remote Execution Contextdist/_node-chunks/run-UOXW6XFP.js
HighRuntime Package Installdist/_node-chunks/run-UOXW6XFP.js
MediumDynamic Requiredist/_node-chunks/run-UOXW6XFP.js
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings