registry  /  @overdeck/core  /  0.45.21

@overdeck/core@0.45.21

Multi-agent orchestration for AI coding assistants (Claude Code, Codex, Cursor, Gemini CLI)

AI Security Review

scanned 1h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. Install-time behavior persists Overdeck-owned hook executables into an existing `~/.overdeck/bin` directory. Runtime agent features may configure a workspace-local Overdeck MCP bridge and call a configured Overdeck dashboard API. No concrete credential exfiltration, remote payload download, or foreign AI-agent control-surface mutation was confirmed.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
`npm install` after Overdeck has been initialized; eligible user-launched Overdeck agents.
Impact
Persistent Overdeck hooks can run in configured agent workflows; this is a guarded lifecycle risk rather than confirmed malicious behavior.
Mechanism
first-party AI-agent hook and MCP bridge setup
Rationale
The package has a real install-time agent-extension lifecycle surface, so it warrants a warning under the firewall policy. Source inspection does not substantiate the scanner's malicious credential-exfiltration or payload claims.
Evidence
package.jsonscripts/postinstall.mjssync-sources/hooks/work-agent-stop-hookdist/agents-C_0ubGr4.jssync-sources/hooks~/.overdeck/bin<workspace>/.pan/agent-mcp.json

Decision evidence

public snapshot
AI called this Suspicious at 94.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • `package.json` runs `scripts/postinstall.mjs` on npm install.
  • `scripts/postinstall.mjs` conditionally creates `~/.overdeck/bin` and copies executable hook files there when `~/.overdeck` exists.
  • `dist/agents-C_0ubGr4.js` can write a workspace-local `.pan/agent-mcp.json` bridge configuration for eligible agent launches.
Evidence against
  • Postinstall targets the package-owned `~/.overdeck` directory and does nothing unless it already exists.
  • Postinstall copies packaged hook files only; it has no network, credential-harvesting, remote-download, or shell-execution path.
  • MCP bridge configuration is guarded by an experimental opt-in and agent/harness eligibility checks.
  • Observed network calls in `work-agent-stop-hook` use configured `PAN_DASHBOARD_URL` for Overdeck dashboard API status/heartbeat operations, not a hard-coded external exfiltration host.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNativeBindingsNetworkShell
Supply chain
HighEntropyStringsMinifiedObfuscatedProtestwareUrlStrings
ManifestNo manifest risk signals triggered.
scanned 1,062 file(s), 29.1 MB of source, external domains: 127.0.0.1, api.anthropic.com, api.cloudflare.com, api.github.com, api.hume.ai, api.kimi.com, api.linear.app, api.machines.dev, api.minimax.io, api.moonshot.ai, api.openai.com, api.vercel.com, api.voyageai.com, api.x.ai, api.z.ai, app.excalidraw.com, bun.sh, chevrotain.io, claude.ai, dashscope-intl.aliyuncs.com, developer.mozilla.org, discord.gg, docker.com, docs.anthropic.com, docs.docker.com, docs.excalidraw.com, docs.expo.dev, docs.github.com, download.pytorch.org, embed.reddit.com, en.wikipedia.org, encoding.spec.whatwg.org, esm.sh, example.com, excalidraw-room-persistence.firebaseio.com, fetch.spec.whatwg.org, fly.io, giphy.com, gist.github.com, github.com, inference-api.nousresearch.com, infra.spec.whatwg.org, jimmy.warting.se, json.excalidraw.com, jsonplaceholder.typicode.com, langium.org, libraries.excalidraw.com, mermaid.js.org, mimesniff.spec.whatwg.org, nodejs.org
Oversized source lightweight scan
dist/dashboard/public/assets/index-SLYGA8AQ.js3.96 MB file, sampled 256 KB
NetworkChildProcessHighEntropyStringsMinifiedUrlStringsgithub.comus.i.posthog.comyandex.com
dist/dashboard/server.js2.16 MB file, sampled 256 KB
FilesystemNetworkChildProcessEnvironmentVarsCryptoShellHighEntropyStringsUrlStringsapi.github.comapi.openai.comopenrouter.ai
dist/dashboard/src-OLoJhUiJ.js5.71 MB file, sampled 256 KB
NetworkChildProcessEnvironmentVarsCryptoHighEntropyStringsUrlStringsgithub.com

Source & flagged code

18 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall.mjs || true
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node scripts/postinstall.mjs || true
Medium
Ambiguous Install Lifecycle Script

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

package.jsonView on unpkg
dist/dashboard/public/assets/chunk-EIO257PC-DnXo63uH.jsView file
22patternName = aws_access_key severity = critical line = 22 matchedText = `,m.push... t};
Critical
Critical Secret

Package contains a critical-looking secret pattern.

dist/dashboard/public/assets/chunk-EIO257PC-DnXo63uH.jsView on unpkg · L22
22patternName = aws_access_key severity = critical line = 22 matchedText = `,m.push... t};
Critical
Secret Pattern

AWS access key ID in dist/dashboard/public/assets/chunk-EIO257PC-DnXo63uH.js

dist/dashboard/public/assets/chunk-EIO257PC-DnXo63uH.jsView on unpkg · L22
dist/pull-requests-DAn4mocc.jsView file
4import { i as setCachedIssuePrTabResponse, n as getIssuePrTabCacheGeneration, r as init_pr_tab_cache, t as getCachedIssuePrTabResponse } from "./pr-tab-cache-D6NXvdC8.js"; L5: import { execFile } from "node:child_process"; L6: import { promisify } from "node:util";
High
Child Process

Package source references child process execution.

dist/pull-requests-DAn4mocc.jsView on unpkg · L4
dist/agents-C_0ubGr4.jsView file
43import { homedir } from "os"; L44: import { exec, execSync } from "child_process"; L45: import { chmodSync as chmodSync$1, closeSync as closeSync$1, constants, copyFileSync as copyFileSync$1, cpSync as cpSync$1, createReadStream as createReadStream$1, existsSync as ex... ... L61: import { fileURLToPath } from "node:url"; L62: import { request } from "node:http"; L63: import { platform as platform$2 } from "process"; ... L104: init_internal_token(); L105: DASHBOARD_URL = process.env["OVERDECK_DASHBOARD_URL"] || "http://127.0.0.1:3011"; L106: DEFAULT_TIMEOUT_MS = 1500; ... L120: const body = yield* Effect.tryPromise({ L121: try: () => res.json(), L122: catch: (cause) => new AgentRuntimeFetchError({
Critical
Credential Exfiltration

Source appears to send environment or credential material to an external endpoint.

dist/agents-C_0ubGr4.jsView on unpkg · L43
2631if (existsSync$1(paths.fifoPath)) unlinkSync$1(paths.fifoPath); L2632: await execAsync$6(`mkfifo -m 600 ${shellQuote(paths.fifoPath)}`); L2633: return paths.fifoPath;
High
Shell

Package source references shell execution.

dist/agents-C_0ubGr4.jsView on unpkg · L2631
scripts/sqlite.mjsView file
2L3: const require = createRequire(import.meta.url); L4: let warningFilterInstalled = false;
Medium
Dynamic Require

Package source references dynamic require/import behavior.

scripts/sqlite.mjsView on unpkg · L2
dist/cli/index.jsView file
95Trigger-reachable chain: manifest.bin -> dist/cli/index.js L95: import { arch, cpus, freemem, homedir, platform, tmpdir, userInfo } from "os"; L96: import { exec, execFile, execFileSync, execSync, spawn, spawnSync } from "child_process"; L97: import { existsSync as existsSync$1, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, readlinkSync as readlinkSync$1, realpathSync as realpat... ... L130: import { createInterface as createInterface$2 } from "readline"; L131: import { stdin, stdout } from "node:process"; L132: //#region src/cli/node-preflight.ts ... L174: } L175: function candidateNodePaths(home = homedir()) { L176: const paths = [ ... L209: if (existsSync("/opt/homebrew/bin/brew") || existsSync("/usr/local/bin/brew")) return "brew install node@22 && brew link --overwrite node@22"; L210: return "Install Node 22 from https://nodejs.org/en/download"; L211: }
Critical
Trigger Reachable Dangerous Capability

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

dist/cli/index.jsView on unpkg · L95
21780console.error(chalk.dim("\nOr download manually from:")); L21781: console.error(chalk.dim(" https://github.[redacted]-compress")); L21782: console.error(chalk.dim(` → place at ${compressDir}/`)); ... L21787: try { L21788: const { stdout, stderr } = await execAsync$8(`python3 __main__.py "${resolvedFile}"`, { L21789: cwd: compressDir, ... L21792: }); L21793: if (stdout) process.stdout.write(stdout); L21794: if (stderr) process.stderr.write(stderr);
High
Command Output Exfiltration

Source combines command execution, command-output handling, and outbound requests; review data flow before blocking.

dist/cli/index.jsView on unpkg · L21780
9871} catch { L9872: execSync("npm install -g @ast-grep/cli", { L9873: stdio: "pipe",
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/cli/index.jsView on unpkg · L9871
95import { arch, cpus, freemem, homedir, platform, tmpdir, userInfo } from "os"; L96: import { exec, execFile, execFileSync, execSync, spawn, spawnSync } from "child_process"; L97: import { existsSync as existsSync$1, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, readlinkSync as readlinkSync$1, realpathSync as realpat... ... L130: import { createInterface as createInterface$2 } from "readline"; L131: import { stdin, stdout } from "node:process"; L132: //#region src/cli/node-preflight.ts ... L174: } L175: function candidateNodePaths(home = homedir()) { L176: const paths = [ ... L209: if (existsSync("/opt/homebrew/bin/brew") || existsSync("/usr/local/bin/brew")) return "brew install node@22 && brew link --overwrite node@22"; L210: return "Install Node 22 from https://nodejs.org/en/download"; L211: }
Medium
Install Persistence

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

dist/cli/index.jsView on unpkg · L95
scripts/create-github-app.mjsView file
12L13: import { createServer } from 'node:http'; L14: import { writeFileSync, mkdirSync } from 'node:fs'; ... L16: import { homedir } from 'node:os'; L17: import { execSync } from 'node:child_process'; L18: import SmeeClient from 'smee-client'; ... L23: L24: if (process.env.OVERDECK_DEV_WEBHOOKS !== '1') { L25: console.error('Refusing to configure a third-party webhook relay outside dev mode.');
High
Same File Env Network Execution

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

scripts/create-github-app.mjsView on unpkg · L12
dist/caveman-compress/__init__.pyView file
path = dist/caveman-compress/__init__.py kind = build_helper sizeBytes = 224 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

dist/caveman-compress/__init__.pyView on unpkg
dist/dashboard/public/assets/space-grotesk-latin-ext-400-normal-CfP_5XZW.woff2View file
path = [redacted]-grotesk-latin-ext-400-normal-CfP_5XZW.woff2 kind = high_entropy_blob sizeBytes = 12256 magicHex = [redacted]
High
Ships High Entropy Blob

Package ships high-entropy non-source blobs.

dist/dashboard/public/assets/space-grotesk-latin-ext-400-normal-CfP_5XZW.woff2View on unpkg
sync-sources/skills/okf/templates/repo/.okf/scripts/okf_common.pyView file
path = sync-[redacted]/.okf/scripts/okf_common.py kind = payload_in_excluded_dir sizeBytes = 5759 magicHex = [redacted]
High
Payload In Excluded Dir

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

sync-sources/skills/okf/templates/repo/.okf/scripts/okf_common.pyView on unpkg
dist/dashboard/server.jsView file
path = dist/dashboard/server.js kind = oversized_source_file sizeBytes = 2259707 magicHex = [redacted]
High
Oversized Source File

Package contains source files above the static scanner size ceiling.

dist/dashboard/server.jsView on unpkg
dist/dashboard/public/assets/chunk-ZUYEQ4TG-B82Qm37l.jsView file
1patternName = google_api_key severity = high line = 1 matchedText = var e={V...AZZX
High
Secret Pattern

Google API key in dist/dashboard/public/assets/chunk-ZUYEQ4TG-B82Qm37l.js

dist/dashboard/public/assets/chunk-ZUYEQ4TG-B82Qm37l.jsView on unpkg · L1

Findings

4 Critical10 High8 Medium7 Low
CriticalCritical Secretdist/dashboard/public/assets/chunk-EIO257PC-DnXo63uH.js
CriticalCredential Exfiltrationdist/agents-C_0ubGr4.js
CriticalTrigger Reachable Dangerous Capabilitydist/cli/index.js
CriticalSecret Patterndist/dashboard/public/assets/chunk-EIO257PC-DnXo63uH.js
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processdist/pull-requests-DAn4mocc.js
HighShelldist/agents-C_0ubGr4.js
HighSame File Env Network Executionscripts/create-github-app.mjs
HighCommand Output Exfiltrationdist/cli/index.js
HighRuntime Package Installdist/cli/index.js
HighShips High Entropy Blobdist/dashboard/public/assets/space-grotesk-latin-ext-400-normal-CfP_5XZW.woff2
HighPayload In Excluded Dirsync-sources/skills/okf/templates/repo/.okf/scripts/okf_common.py
HighOversized Source Filedist/dashboard/server.js
HighSecret Patterndist/dashboard/public/assets/chunk-ZUYEQ4TG-B82Qm37l.js
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requirescripts/sqlite.mjs
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/cli/index.js
MediumProtestware
MediumShips Build Helperdist/caveman-compress/__init__.py
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowEval
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowUrl Strings