registry  /  @polymorphism-tech/morph-spec  /  7.8.0

@polymorphism-tech/morph-spec@7.8.0

MORPH-SPEC: NLH (Natural Language Harness) for spec-driven development with Claude Code

AI Security Review

scanned 4h ago · by lpm-firewall-ai

LPM blocks this version under the AI-agent control-surface policy. Install-time code mutates the global Claude Code control surface. It installs a statusline command into the user's global `~/.claude/settings.json` without an explicit user command or opt-in.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
npm postinstall
Impact
Persists package-controlled executable configuration across Claude Code sessions and alters user shell startup configuration.
Mechanism
Global Claude Code settings and shell-profile mutation
Policy narrative
Installing the package automatically executes `global-install.js`. That script calls `installGlobalStatusline`, which copies package statusline assets into `~/.claude` and writes a global `settings.json` `statusLine.command` pointing to them. On Windows it also appends a PATH modification to PowerShell profiles. This is an unconsented postinstall mutation of a broad, foreign AI-agent control surface.
Rationale
The install hook performs concrete persistence into global Claude Code configuration rather than limiting setup to an explicit user command or project-local configuration. Under the firewall policy, this requires blocking even though the payload is feature-aligned.
Evidence
package.jsonsrc/scripts/global-install.jssrc/utils/hooks-installer.jsframework/hooks/claude-code/statusline.sh~/.claude/settings.json~/Documents/PowerShell/Microsoft.PowerShell_profile.ps1~/Documents/WindowsPowerShell/Microsoft.PowerShell_profile.ps1

Decision evidence

public snapshot
AI called this Malicious at 98.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for policy block
  • `package.json` runs `src/scripts/global-install.js` as `postinstall`.
  • `src/scripts/global-install.js` invokes `installGlobalStatusline()` without consent.
  • `src/utils/hooks-installer.js` writes `~/.claude/settings.json` and replaces `statusLine`.
  • Postinstall also writes Windows PowerShell profiles to alter PATH.
Evidence against
  • No credential collection or network request appears in the postinstall path.
  • MCP credential setup is interactive under explicit CLI/init flows, not postinstall.
Behavioral surface
Source
ChildProcessEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 140 file(s), 858 KB of source, external domains: cli.github.com, cloud.google.com, contrast-ratio.com, json.schemastore.org, raw.githubusercontent.com, registry.npmjs.org, stitch.googleapis.com, www.python.org

Source & flagged code

9 flagged · loading source
package.jsonView file
scripts.postinstall = node src/scripts/global-install.js
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
framework/hooks/claude-code/core/post-edit-typecheck.jsView file
16L17: import { execSync } from 'child_process'; L18: import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
High
Child Process

Package source references child process execution.

framework/hooks/claude-code/core/post-edit-typecheck.jsView on unpkg · L16
7* L8: * Runs `npx tsc --noEmit` only for .ts/.tsx files, with a 3-second debounce L9: * so rapid sequential edits (e.g. multiple files in one task) don't each ... L16: L17: import { execSync } from 'child_process'; L18: import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

framework/hooks/claude-code/core/post-edit-typecheck.jsView on unpkg · L7
src/scripts/global-install.jsView file
14* Ensure the npm global bin directory is in the user's PATH on Windows. L15: * Adds it to the PowerShell $PROFILE so new terminals find `morph-spec`. L16: */
High
Shell

Package source references shell execution.

src/scripts/global-install.jsView on unpkg · L14
src/lib/installers/mcp-installer.jsView file
189*/ L190: const { execSync } = require('child_process'); L191: const { createInterface } = require('readline'); L192: L193: const STITCH_URL = 'https://stitch.googleapis.com/mcp'; L194: const PROJECT_ID = '${gcpProject}'; ... L197: const GCLOUD = process.platform === 'win32' L198: ? (process.env.LOCALAPPDATA || '') + '/Google/Cloud SDK/google-cloud-sdk/bin/gcloud.cmd' L199: : 'gcloud';
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

src/lib/installers/mcp-installer.jsView on unpkg · L189
src/utils/hooks-installer.jsView file
matchType = previous_version_dangerous_delta matchedPackage = @polymorphism-tech/morph-spec@7.9.0 matchedIdentity = npm:[redacted]:7.9.0 similarity = 0.900 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.

src/utils/hooks-installer.jsView on unpkg
14import { homedir } from 'os'; L15: import { execSync } from 'child_process'; L16: ... L184: try { L185: settings = JSON.parse(await readFile(settingsPath, 'utf-8')); L186: } catch { ... L261: // JSON Schema for IDE auto-complete and validation L262: settings['$schema'] = 'https://json.schemastore.org/claude-code-settings.json'; L263: ... L304: function findPython() { L305: if (process.platform !== 'win32') { L306: for (const cmd of ['python3', 'python']) {
High
Sandbox Evasion Gated Capability

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

src/utils/hooks-installer.jsView on unpkg · L14
framework/hooks/claude-code/statusline.pyView file
path = framework/hooks/claude-code/statusline.py kind = build_helper sizeBytes = 25708 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

framework/hooks/claude-code/statusline.pyView on unpkg
framework/templates/meta-prompts/validators/pre-commit-validator.mdView file
34patternName = private_key_rsa severity = critical line = 34 matchedText = - Privat...---)
Critical
Secret Pattern

RSA private key in framework/templates/meta-prompts/validators/pre-commit-validator.md

framework/templates/meta-prompts/validators/pre-commit-validator.mdView on unpkg · L34

Findings

2 Critical6 High4 Medium5 Low
CriticalPrevious Version Dangerous Deltasrc/utils/hooks-installer.js
CriticalSecret Patternframework/templates/meta-prompts/validators/pre-commit-validator.md
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processframework/hooks/claude-code/core/post-edit-typecheck.js
HighShellsrc/scripts/global-install.js
HighSame File Env Network Executionsrc/lib/installers/mcp-installer.js
HighSandbox Evasion Gated Capabilitysrc/utils/hooks-installer.js
HighRuntime Package Installframework/hooks/claude-code/core/post-edit-typecheck.js
MediumNetwork
MediumEnvironment Vars
MediumShips Build Helperframework/hooks/claude-code/statusline.py
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License