registry  /  karajan-code  /  3.12.2

karajan-code@3.12.2

Local multi-agent coding orchestrator with TDD, SonarQube, and code review pipeline

AI Security Review

scanned 2h ago · by lpm-firewall-ai

LPM blocks this version under the AI-agent control-surface policy. Installing the package invokes an unguarded postinstall hook. It modifies Claude Code and Codex global MCP configuration to register a package-controlled server.

Static reason
High-risk behavior combination matched malicious policy.; source matched previously finalized malicious package; routed for review
Trigger
npm install of karajan-code@3.12.2
Impact
Future Claude Code or Codex sessions can start the package-controlled MCP server with its exposed tools.
Mechanism
Unconsented postinstall mutation of global AI-agent MCP configuration
Policy narrative
On npm installation, `scripts/postinstall.js` reads or creates global Claude Code and Codex configuration files, then registers `karajan-mcp` to execute the installed package's MCP server. This happens without an explicit user command or consent and is idempotent, so the package persists control over a broad AI-agent integration surface across later sessions. The hook suppresses failures, reducing visibility of the mutation.
Rationale
Source inspection confirms a concrete unconsented postinstall write to foreign global AI-agent control surfaces. Under the firewall policy, this requires blocking regardless of the absence of observed exfiltration.
Evidence
package.jsonscripts/postinstall.jssrc/mcp/server.jssrc/mcp/tools.js~/.claude.json~/.codex/config.toml~/.karajan/instances.json

Decision evidence

public snapshot
AI called this Malicious at 99.0% confidence as Malware with low false-positive risk.
Evidence for policy block
  • `package.json` declares `postinstall: node scripts/postinstall.js`.
  • `scripts/postinstall.js` unconditionally rewrites `~/.claude.json` to add `karajan-mcp`.
  • It rewrites `~/.codex/config.toml` with an MCP server block.
  • The injected server executes the package-local `src/mcp/server.js` via Node.
  • Errors are swallowed, so installation completes even if mutation is partially hidden.
Evidence against
  • No install-time network request or credential exfiltration was found in `scripts/postinstall.js`.
  • The installed MCP command points to package-local source rather than a downloaded payload.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNativeBindingsNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
CopyleftLicense
scanned 569 file(s), 2.90 MB of source, external domains: aider.chat, aistudio.google.com, api.cohere.com, api.mistral.ai, api.openai.com, api.voyageai.com, cli.github.com, console.anthropic.com, developers.openai.com, docs.anthropic.com, docs.docker.com, docs.sonarsource.com, fonts.googleapis.com, fonts.gstatic.com, get.docker.com, git-scm.com, github.com, google.github.io, karajan-code.web.app, karajancode.com, nodejs.org, opencode.ai, platform.openai.com, raw.githubusercontent.com, registry.npmjs.org, semgrep.dev, sonarcloud.io, www.docker.com, www.w3.org

Source & flagged code

16 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall.js
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node scripts/postinstall.js
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
scripts/diet-baseline.mjsView file
25L26: import { execFileSync, spawnSync } from "node:child_process"; L27: import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
High
Child Process

Package source references child process execution.

scripts/diet-baseline.mjsView on unpkg · L25
src/agents/resolve-bin.jsView file
65L66: // 3. Fallback: return name as-is (let execa try PATH) L67: cache.set(name, name);
High
Shell

Package source references shell execution.

src/agents/resolve-bin.jsView on unpkg · L65
packages/hu-board/src/boot-info.jsView file
12L13: const require = createRequire(import.meta.url); L14: export const PKG_VERSION = (() => {
Medium
Dynamic Require

Package source references dynamic require/import behavior.

packages/hu-board/src/boot-info.jsView on unpkg · L12
src/sonar/project-key.jsView file
59const explicit = String( L60: options.projectKey || process.env.KJ_SONAR_PROJECT_KEY || config?.sonarqube?.project_key || "" L61: ).trim(); ... L66: const remote = await runCommand("git", ["config", "--get", "remote.origin.url"]); L67: const remoteUrl = String(remote.stdout || "").trim(); L68: if (remote.exitCode !== 0 || !remoteUrl) {
Low
Weak Crypto

Package source references weak cryptographic algorithms.

src/sonar/project-key.jsView on unpkg · L59
scripts/install.jsView file
matchType = normalized_sha256 matchedPackage = karajan-code@3.9.0 matchedPath = scripts/install.js matchedIdentity = npm:a2FyYWphbi1jb2Rl:3.9.0 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.

scripts/install.jsView on unpkg
4import path from "node:path"; L5: import { spawn } from "node:child_process"; L6: import readline from "node:readline/promises"; L7: import { stdin as input, stdout as output } from "node:process"; L8: L9: const rl = readline.createInterface({ input, output }); L10: const REGISTRY_PATH = path.join(os.homedir(), ".karajan", "instances.json"); L11: const INSTALL_STATE_PATH = path.join(os.homedir(), ".karajan", "install-state.json"); L12: const AGENT_META = { L13: codex: { bin: "codex", installUrl: "https://developers.openai.com/codex/cli" }, L14: claude: { bin: "claude", installUrl: "https://docs.anthropic.com/en/docs/claude-code" }, ... L119: if (cliValue !== undefined) return cliValue;
Medium
Install Persistence

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

scripts/install.jsView on unpkg · L4
scripts/postinstall.jsView file
3Install-time AI-agent control hijack evidence: L25: await fs.mkdir(path.dirname(file), { recursive: true }); L26: await fs.writeFile(file, `${JSON.stringify(obj, null, 2)}\n`, "utf8"); L27: } ... L48: async function setupClaudeMcp(kjHome) { L49: const claudeJsonPath = path.join(os.homedir(), ".claude.json"); L50: let config = {}; ... L56: L57: config.mcpServers = config.mcpServers || {}; L58: config.mcpServers["karajan-mcp"] = { L59: type: "stdio", ... L83: async function setupCodexMcp(kjHome) { L84: const configPath = path.join(os.homedir(), ".codex", "config.toml"); Payload evidence from src/agents/resolve-bin.js: L3: import os from "node:os"; L4: import { execFileSync } from "node:child_process"; L5: ... L7: L8: const isWin = process.platform === "win32"; L9: ... L11: ? [ L12: path.join(os.homedir(), "AppData", "Roaming", "npm"), L13: path.join(os.homedir(), "AppData", "Local", "npm"), ... L24: function getNvmDirs() { L25: const nvmDir = process.env.NVM_DIR || path.join(os.homedir(), ".nvm"); L26: const versionsDir = path.join(nvmDir, "versions", "node");
Critical
Ai Agent Control Hijack

Install-time source drops package-supplied AI-agent/MCP control files or instructions.

scripts/postinstall.jsView on unpkg · L3
src/audit/basal-cost.jsView file
76return new Promise((resolve) => { L77: execFile("npx", ["depcheck", "--json"], { cwd: projectDir, timeout: 30000 }, (err, stdout) => { L78: if (err && !stdout) {
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

src/audit/basal-cost.jsView on unpkg · L76
vendor/tree-sitter-grammars/python.wasmView file
path = vendor/tree-sitter-grammars/python.wasm kind = wasm_module sizeBytes = 457883 magicHex = [redacted]
Medium
Ships Wasm Module

Package ships WebAssembly modules.

vendor/tree-sitter-grammars/python.wasmView on unpkg
scripts/install-binary.shView file
path = scripts/install-binary.sh kind = build_helper sizeBytes = 4198 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

scripts/install-binary.shView on unpkg
packages/hu-board/src/server.jsView file
matchType = normalized_sha256 matchedPackage = karajan-code@3.9.0 matchedPath = packages/hu-board/src/server.js matchedIdentity = npm:a2FyYWphbi1jb2Rl:3.9.0 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.

packages/hu-board/src/server.jsView on unpkg
packages/ai-trash/src/git-snapshot.jsView file
matchType = normalized_sha256 matchedPackage = karajan-code@3.9.0 matchedPath = packages/ai-trash/src/git-snapshot.js matchedIdentity = npm:a2FyYWphbi1jb2Rl:3.9.0 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.

packages/ai-trash/src/git-snapshot.jsView on unpkg
packages/hu-board/src/command-runner.jsView file
matchType = normalized_sha256 matchedPackage = karajan-code@3.9.0 matchedPath = packages/hu-board/src/command-runner.js matchedIdentity = npm:a2FyYWphbi1jb2Rl:3.9.0 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.

packages/hu-board/src/command-runner.jsView on unpkg
packages/hu-board/src/plan-mutations.jsView file
matchType = normalized_sha256 matchedPackage = karajan-code@3.9.0 matchedPath = packages/hu-board/src/plan-mutations.js matchedIdentity = npm:a2FyYWphbi1jb2Rl:3.9.0 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.

packages/hu-board/src/plan-mutations.jsView on unpkg

Findings

1 Critical9 High8 Medium7 Low
CriticalAi Agent Control Hijackscripts/postinstall.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processscripts/diet-baseline.mjs
HighShellsrc/agents/resolve-bin.js
HighRuntime Package Installsrc/audit/basal-cost.js
HighKnown Malware Source Similaritypackages/hu-board/src/server.js
HighKnown Malware Source Similarityscripts/install.js
HighKnown Malware Source Similaritypackages/ai-trash/src/git-snapshot.js
HighKnown Malware Source Similaritypackages/hu-board/src/command-runner.js
HighKnown Malware Source Similaritypackages/hu-board/src/plan-mutations.js
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requirepackages/hu-board/src/boot-info.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencescripts/install.js
MediumShips Wasm Modulevendor/tree-sitter-grammars/python.wasm
MediumShips Build Helperscripts/install-binary.sh
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowWeak Cryptosrc/sonar/project-key.js
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowCopyleft License