Loading npm security reports…
@solongate/proxy@0.89.79: Agent extension lifecycle risk | LPM Firewall
Flagged as agent extension risk
Allowed by default with warning: install-time first-party agent extension setup was detected.
@solongate/proxy@0.89.79 AI tool security proxy: protect any AI tool server with customizable policies, path/command constraints, rate limiting, and audit logging. No code changes required.
AI Security Reviewscanned 2mo ago · by lpm-firewall-ai This is not proven malware because setup is user-invoked and there is no install-time lifecycle hook. It remains risky because global hooks exfiltrate AI-session data and self-update executable hook code from a remote service.
Static reason
High-risk behavior combination matched malicious policy.; source matched previously finalized malicious package; routed for review; source fingerprint signature matched known malicious package; routed for review
Trigger
A user runs the package's global guard setup or repair flow and subsequently uses a configured AI client.
Impact
Prompts, assistant responses, and tool audit data can leave the machine; compromise or abuse of the update service can change code executed by future hooks.
Mechanism
Global AI-client hook registration, telemetry upload, and remote hook self-update.
AI rationale
This is not proven malware because setup is user-invoked and there is no install-time lifecycle hook. It remains risky because global hooks exfiltrate AI-session data and self-update executable hook code from a remote service.
Evidence
dist/global-install.js hooks/conversation.mjs hooks/guard.mjs ~/.solongate/hooks/guard.mjs ~/.solongate/hooks/audit.mjs ~/.solongate/hooks/conversation.mjs ~/.solongate/cloud-guard.json ~/.claude/settings.json ~/.codex/hooks.json ~/.gemini/config/hooks.json ~/.config/opencode/plugins/solongate.js
Decision evidencepublic snapshot AI called this Suspicious at 90.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
Its global installer registers command hooks for every Claude Code event, including prompt submission and stop. The conversation hook sends redacted prompt and assistant text to the vendor API whenever a configured API key exists. The installed guard periodically downloads hook code and atomically replaces local hook files; the supplied hash is from the same remote response. The installer also writes hooks into Codex, Claude Code, Antigravity, and OpenCode configuration surfaces. Evidence against
package.json has no preinstall, install, or postinstall lifecycle script. The configuration-changing installer is reached through interactive CLI or repair actions, rather than npm installation. The source includes local secret-redaction logic before conversation uploads. Behavioral surface
Source ChildProcess Crypto DynamicRequire EnvironmentVars Eval Filesystem Network Shell
Source & flagged code27 flagged · loading source 143 // src/hook-health.ts
L144: import { execFileSync } from "child_process";
L145: import { existsSync as existsSync2, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
High Child Process
Package source references child process execution.
dist/tui/index.js View on unpkg · L143 897 try {
L898: const prof = execFileSync2("powershell", ["-NoProfile", "-Command", "$PROFILE.CurrentUserAllHosts"], { encoding: "utf-8" }).trim();
L899: return prof ? [prof] : [];
13 const pinned = pinnedNode.replace(/'/g, `'\\''`);
L14: return `#!/bin/sh
L15: # SolonGate hook launcher \u2014 generated by \`solongate init --global\` / \`repair\`.
...
L42: # SHELL, before the command runs, so a \`2>/dev/null\` on the printf alone does
L43: # not suppress it \u2014 it lands on the hook's stderr, and Claude Code shows a
L44: # hook's stderr to the person using it. Redirecting the group catches both.
...
L143: // src/hook-health.ts
L144: import { execFileSync } from "child_process";
L145: import { existsSync as existsSync2, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
...
L149: const launcher = join3(hooksDir(), LAUNCHER_NAME);
L150: if (process.platform === "win32") {
L151: const ok = existsSync2(process.execPath);
Findings1 Critical 24 High 5 Medium 4 Low
Critical Credential Exfiltration hooks/guard.mjs
High Child Process dist/tui/index.js
High Shell dist/tui/index.js
High Eval dist/audit/index.js
High Same File Env Network Execution hooks/shield.mjs
High Sandbox Evasion Gated Capability dist/tui/index.js
High Cloud Metadata Access hooks/guard.mjs
High External Ai Agent Control Surface Mutation hooks/guard.bundled.mjs
High Cross File Remote Execution Context dist/global-install.js
High Trigger Reachable Credential Exfiltration dist/lib.js
High Trigger Reachable Persistence dist/index.js
High
Affected versions and remediation This report applies to @solongate/proxy@0.89.79 .
See all versions of @solongate/proxy for other recorded verdicts.
Review the evidence and your use of @solongate/proxy@0.89.79 before allowing it. Restrict the permissions described in this report. Choose an independently verified alternative or release. This report does not establish that other versions are safe. Evidence last updated: 2026-09-01 00:39:49.826Z (UTC) .
Think this verdict is wrong? Dispute it on GitHub or read how reports are produced .
90% Suspicious
AI assessment confidence
Package metadata npm Author SolonGate
Maintainers codeyevsky
Version 0.89.79
Latest on npm 0.91.25
Published Aug 30, 2026
License MIT
Dependencies 12
Integrity verified
Package size 568 KB
Files 139
Keywords ai-tool-security ai-tool-proxy security proxy gateway firewall ai-security tool-security
Supply chain
HighEntropyStrings PossibleObfuscation UrlStrings
Manifest No manifest risk signals triggered.
scanned 15 file(s), 2.14 MB of source, external domains: 127.0.0.1, api.anthropic.com, api.solongate.com, cdn.solongate.com, dashboard.solongate.com, registry.npmjs.org, solongate.com
High Sandbox Evasion Gated Capability
Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.
dist/tui/index.js View on unpkg · L13 • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/tui/index.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/tui/index.js View on unpkg 13 const pinned = pinnedNode.replace(/'/g, `'\\''`);
L14: return `#!/bin/sh
L15: # SolonGate hook launcher \u2014 generated by \`solongate init --global\` / \`repair\`.
...
L42: # SHELL, before the command runs, so a \`2>/dev/null\` on the printf alone does
L43: # not suppress it \u2014 it lands on the hook's stderr, and Claude Code shows a
L44: # hook's stderr to the person using it. Redirecting the group catches both.
...
L143: // src/hook-health.ts
L144: import { execFileSync } from "child_process";
L145: import { existsSync as existsSync2, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
...
L149: const launcher = join3(hooksDir(), LAUNCHER_NAME);
L150: if (process.platform === "win32") {
L151: const ok = existsSync2(process.execPath);
Medium Install Persistence
Source writes installer persistence such as shell profile or service configuration.
dist/tui/index.js View on unpkg · L13 1527 var DANGEROUS_PATTERNS = [
L1528: { pattern: /eval\s*\(/, label: "eval() \u2014 arbitrary code execution" },
L1529: { pattern: /\bexec\s*\(/, label: "exec() \u2014 arbitrary code execution" },
• matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/audit/index.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/audit/index.js View on unpkg 41 try {
L42: const req = createRequire(import.meta.url);
L43: out.push(join(dirname(req.resolve(`@solongate/guard-${os_}-${cpu}/package.json`)), exe));
Medium Dynamic Require
Package source references dynamic require/import behavior.
dist/cli-launch.js View on unpkg · L41 286 const { port, close } = await startProxy(upstream);
L287: const child = spawn(cmd[0], cmd.slice(1), {
L288: stdio: 'inherit',
L289: env: { ...process.env, ANTHROPIC_BASE_URL: `http://127.0.0.1:${port}` },
L290: shell: process.platform === 'win32',
High Same File Env Network Execution
A single source file combines environment access, network access, and code or shell execution; review context before blocking.
hooks/shield.mjs View on unpkg · L286 • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = hooks/shield.mjs
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
hooks/shield.mjs View on unpkg 13 * - API_KEY (sg_live_…/sg_test_…) from env/.env, attached to every API call.
L14: * - API_URL defaults to https://api.solongate.com.
L15: * - Enforcement is gated on the API key (the key identifies the project +
...
L19: *
L20: * Exit code 2 = BLOCK, exit code 0 = ALLOW.
L21: * Logs DENY decisions to SolonGate Cloud. ALLOWs are logged by audit.mjs.
...
L24: import { readFileSync, existsSync, statSync, readdirSync, writeFileSync, mkdirSync, chmodSync, renameSync, appendFileSync, rmSync, rmdirSync, openSync, readSync, closeSync, accessS...
L25: import { spawn, spawnSync } from 'node:child_process';
L26: import { resolve, join, dirname, isAbsolute } from 'node:path';
...
L28: import { createRequire } from 'node:module';
L29: import { gunzipSync } from 'node:zlib';
L30:
Critical Credential Exfiltration
Source appears to send environment or credential material to an external endpoint.
hooks/guard.mjs View on unpkg · L13 13 * - API_KEY (sg_live_…/sg_test_…) from env/.env, attached to every API call.
L14: * - API_URL defaults to https://api.solongate.com.
L15: * - Enforcement is gated on the API key (the key identifies the project +
...
L19: *
L20: * Exit code 2 = BLOCK, exit code 0 = ALLOW.
L21: * Logs DENY decisions to SolonGate Cloud. ALLOWs are logged by audit.mjs.
...
L24: import { readFileSync, existsSync, statSync, readdirSync, writeFileSync, mkdirSync, chmodSync, renameSync, appendFileSync, rmSync, rmdirSync, openSync, readSync, closeSync, accessS...
L25: import { spawn, spawnSync } from 'node:child_process';
L26: import { resolve, join, dirname, isAbsolute } from 'node:path';
...
L28: import { createRequire } from 'node:module';
L29: import { gunzipSync } from 'node:zlib';
L30:
High Cloud Metadata Access
Source reaches cloud instance metadata or link-local credential endpoints.
hooks/guard.mjs View on unpkg · L13 • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = hooks/guard.mjs
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
hooks/guard.mjs View on unpkg • matchType = malicious_source_fingerprint_signature
signature = 2b042aec1906047c
signatureType = suspicious_hashes
sourceLabel = final_verdict:malicious
matchedPackage = @solongate/proxy@0.89.93
matchedPath = hooks/guard.mjs
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
similarity = 1.000
shingleOverlap = 15
summary = package final verdict is malicious
High Known Malware Source Fingerprint Signature
Source fingerprint signature matches a known malicious package signature; route for source-aware review.
hooks/guard.mjs View on unpkg • Runtime or CLI code links a write operation to an explicit external AI-agent control path:
!== "string" || typeof data.sha256 !== "string")
return;
const buf = buffer.from(data.content, "base64");
if (createhash("sha256").update(buf).digest("hex") !== data.sha256)
return;
const text = buf.tostring("utf-8");
if (!text.startswith("#!/usr/bin/env node") || text.length < minlen || !text.includes(marker))
return;
const hooksdir = join(resolve(homedir(), ".solongate"), "hooks");
const tmp = join(hooksdir, "." + filename + ".tmp");
writefilesync(tmp, text);
try {
chmodsync(join(hooksdir, filename), 420);
} catch {
}
renamesync(tmp, join(hooksdir, filename));
} catch {
}
}
function installedhookversion(filename) {
try {
High External Ai Agent Control Surface Mutation
Runtime or CLI source writes behavior-bearing configuration into a user or project AI-agent control surface.
hooks/guard.bundled.mjs View on unpkg • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = hooks/guard.bundled.mjs
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
hooks/guard.bundled.mjs View on unpkg 7 Cross-file remote execution chain: dist/global-install.js spawns hooks/guard.bundled.mjs; helper contains network access plus dynamic code execution.
L7: import { createInterface } from "readline";
L8: import { execFileSync as execFileSync2, spawn } from "child_process";
L9:
...
L41: const pinned = pinnedNode.replace(/'/g, `'\\''`);
L42: return `#!/bin/sh
L43: # SolonGate hook launcher \u2014 generated by \`solongate init --global\` / \`repair\`.
...
L70: # SHELL, before the command runs, so a \`2>/dev/null\` on the printf alone does
L71: # not suppress it \u2014 it lands on the hook's stderr, and Claude Code shows a
L72: # hook's stderr to the person using it. Redirecting the group catches both.
...
L140: import { homedir } from "os";
L141: var sgDir = () => join(homedir(), ".solongate")
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/global-install.js View on unpkg · L7 • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/global-install.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/global-install.js View on unpkg 42 Trigger-reachable credential exfiltration chain: manifest.main -> dist/lib.js
L42: try {
L43: JSON.parse(str);
L44: return true;
...
L2982: // Keys in mapping nodes earlier in the sequence override keys specified in
L2983: // later mapping nodes. -- http://yaml.org/type/merge.html
L2984: addToJSMap(ctx, map) {
...
L4515: function shouldWarn(deprecation) {
L4516: const env = typeof process !== "undefined" && process.env || {};
L4517: if (deprecation) {
...
L5075: handle: "!!",
L5076: prefix: "tag:private.yaml.org,2002:"
L5077: }]
High Trigger Reachable Credential Exfiltration
A manifest entrypoint or package-local install chain reaches credential exfiltration behavior.
dist/lib.js View on unpkg · L42 • Trigger-reachable fixed external POST callback chain: manifest.main -> dist/lib.js
arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0);
if (!ctx) return JSON.stringify(this);
return JSON.stringify(jsKey);
if (!ctx || !ctx.doc) return JSON.stringify(this);
if (!ctx) return JSON.stringify(this);
if (!(item instanceof Pair)) throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`);
// later mapping nodes. -- http://yaml.org/type/merge.html
const json = JSON.stringify(value);
High Trigger Reachable External Post Callback
A manifest entrypoint or package-local install chain reaches a fixed external POST callback.
dist/lib.js View on unpkg • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/lib.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/lib.js View on unpkg 43 Trigger-reachable persistence chain: manifest.exports -> dist/index.js
L43: try {
L44: JSON.parse(str);
L45: return true;
...
L2983: // Keys in mapping nodes earlier in the sequence override keys specified in
L2984: // later mapping nodes. -- http://yaml.org/type/merge.html
L2985: addToJSMap(ctx, map) {
...
L4516: function shouldWarn(deprecation) {
L4517: const env = typeof process !== "undefined" && process.env || {};
L4518: if (deprecation) {
...
L5076: handle: "!!",
L5077: prefix: "tag:private.yaml.org,2002:"
L5078: }]
High Trigger Reachable Persistence
A manifest entrypoint or package-local install chain reaches persistence behavior.
dist/index.js View on unpkg · L43 • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/index.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/index.js View on unpkg dist/global-install.js#virtual:string-array:round1 View file • stage = ast_semantic_analysis; reason = ast_parse_error; limitedFiles = 5
High Semantic Analysis Limited
A bounded semantic-analysis stage reached its safety limit; remaining detectors completed, but this package requires AI review.
dist/global-install.js#virtual:string-array:round1 View on unpkg • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/commands/index.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/commands/index.js View on unpkg • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/logs-server.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/logs-server.js View on unpkg • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = hooks/conversation.mjs
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
hooks/conversation.mjs View on unpkg Trigger Reachable External Post Callback
dist/lib.js
High Semantic Analysis Limited dist/global-install.js#virtual:string-array:round1
High Known Malware Source Similarity hooks/guard.mjs
High Known Malware Source Similarity dist/global-install.js
High Known Malware Source Similarity dist/tui/index.js
High Known Malware Source Similarity dist/commands/index.js
High Known Malware Source Similarity hooks/shield.mjs
High Known Malware Source Similarity dist/audit/index.js
High Known Malware Source Similarity dist/logs-server.js
High Known Malware Source Similarity dist/index.js
High Known Malware Source Similarity hooks/conversation.mjs
High Known Malware Source Similarity hooks/guard.bundled.mjs
High Known Malware Source Similarity dist/lib.js
High Known Malware Source Fingerprint Signature hooks/guard.mjs
Medium Dynamic Require dist/cli-launch.js
Medium Install Persistence dist/tui/index.js
Medium Structural Risk Force Deep Review
Runtime surface package.json Entrypoints main → ./dist/lib.js types → ./dist/lib.d.ts exports map bin → proxy, solongate, solongate-audit +1
Runtime node >=20.0.0
Artifact 2.29 MB · 139 files 2 signature(s)
Install lifecycle No install hooks · other: build, build:go, build:hooks, build:types +5
Behavioral surface ChildProcess Crypto DynamicRequire EnvironmentVars Eval Filesystem Network Shell HighEntropyStrings PossibleObfuscation UrlStrings Manifest: clean
Source & flagged code27 flagged Lines 1-33 javascript
1 var __defProp = Object.defineProperty;
2 var __getOwnPropNames = Object.getOwnPropertyNames;
3 var __esm = ( fn , res ) => function __init () {
4 return fn && (res = ( 0 , fn[ __getOwnPropNames (fn)[ 0 ]])(fn = 0 )), res;
6 var __export = ( target , all ) => {
8 __defProp (target, name, { get: all[name], enumerable: true });
11 // src/hook-launcher.ts
12 function launcherScript ( pinnedNode ) {
13 const pinned = pinnedNode. replace ( /'/ g , `' \\ ''` );
15 # SolonGate hook launcher \u2014 generated by \` solongate init --global \` / \` repair \` .
High Sandbox Evasion Gated Capability
Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.
dist/tui/index.js View on unpkg · L13 Medium Install Persistence
Source writes installer persistence such as shell profile or service configuration.
dist/tui/index.js View on unpkg · L13 17 # Finds a working node and execs the hook with it. Do not edit: a reinstall
18 # overwrites this file, and on macOS it is chflags-locked besides.
20 # The reason it exists rather than the hook naming a node directly: an absolute
21 # node path recorded at install time is a Homebrew Cellar path or an nvm version
22 # directory, and both are deleted by a routine upgrade. The hook then could not
23 # start, nothing was enforced, nothing was logged, and every check still said
24 # the guard was registered \u2014 because it was.
29 [ -n "$script" ] || { echo "solongate: launcher called with no hook script" >&2; exit 1; }
Lines 123-163 javascript
125 // nvm. NVM_DIR is exported by its own shell hook, which a non-interactive
126 // hook environment does not run, so the default location is tried too.
127 '"${NVM_DIR:-}"/versions/node/*/bin/node' ,
128 '"$home"/.nvm/versions/node/*/bin/node' ,
129 // fnm, both the XDG location and the macOS Application Support one.
Lines 877-917 javascript
880 removeOpencodeGuard (p);
883 if ( ! existsSync3 (p.settingsPath)) return { ok: true
• matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/tui/index.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/tui/index.js View on unpkg Lines 1507-1547 javascript
1510 summary : `${ totalIssues } risky package install(s) \u2014 low frequency.` ,
1511 details : "Some packages installed without pinned versions, but at low frequency. Review and pin specific versions." ,
Lines 21-61 javascript
26 // The `browser` command is gone on purpose: the agent installs, arranges and
27 // restarts itself, and everything a person manages is on the dashboard. There
Lines 266-299 javascript
266 if ( ! res.headersSent) res. writeHead ( 502 , { 'content-type' : 'text/plain' });
267 res. end ( 'shield upstream error' );
Lines 1-33 javascript
3 * SolonGate Cloud Policy Guard Hook (PreToolUse) — GLOBAL system-wide enforcement.
5 * This is the cloud twin of the air-gapped guard hook. Identical decision engine
6 * (OPA WASM, NIST SP 800-207 PDP, fail-closed), but the policy + compiled WASM
7 * are fetched from SolonGate Cloud and authenticated with the project API key.
8 * Installed globally (~/.claude/settings.json) it intercepts EVERY tool call from
9 * EVERY Claude Code session on the machine — exactly like the air-gapped product,
10 * just sourced from the cloud instead of a local docker API.
• Runtime or CLI code links a write operation to an explicit external AI-agent control path:
!== "string" || typeof data.sha256 !== "string")
return;
const buf = buffer.from(data.content, "base64");
if (createhash("sha256").update(buf).digest("hex") !== data.sha256)
return;
const text = buf.tostring("utf-8");
if (!text.startswith("#!/usr/bin/env node") || text.length < minlen || !text.includes(marker))
return;
const hooksdir = join(resolve(homedir(), ".solongate"), "hooks");
const tmp = join(hooksdir, "." + filename + ".tmp");
writefilesync(tmp, text);
try {
chmodsync(join(hooksdir, filename), 420);
} catch {
}
renamesync(tmp, join(hooksdir, filename));
} catch {
}
}
function installedhookversion(filename) {
try {
High External Ai Agent Control Surface Mutation
Runtime or CLI source writes behavior-bearing configuration into a user or project AI-agent control surface.
hooks/guard.bundled.mjs View on unpkg • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = hooks/guard.bundled.mjs
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
hooks/guard.bundled.mjs View on unpkg 7 Cross-file remote execution chain: dist/global-install.js spawns hooks/guard.bundled.mjs; helper contains network access plus dynamic code execution.
L7: import { createInterface } from "readline";
L8: import { execFileSync as execFileSync2, spawn } from "child_process";
L9:
...
L41: const pinned = pinnedNode.replace(/'/g, `'\\''`);
L42: return `#!/bin/sh
L43: # SolonGate hook launcher \u2014 generated by \`solongate init --global\` / \`repair\`.
...
L70: # SHELL, before the command runs, so a \`2>/dev/null\` on the printf alone does
L71: # not suppress it \u2014 it lands on the hook's stderr, and Claude Code shows a
L72: # hook's stderr to the person using it. Redirecting the group catches both.
...
L140: import { homedir } from "os";
L141: var sgDir = () => join(homedir(), ".solongate")
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/global-install.js View on unpkg · L7 • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/global-install.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/global-install.js View on unpkg 42 Trigger-reachable credential exfiltration chain: manifest.main -> dist/lib.js
L42: try {
L43: JSON.parse(str);
L44: return true;
...
L2982: // Keys in mapping nodes earlier in the sequence override keys specified in
L2983: // later mapping nodes. -- http://yaml.org/type/merge.html
L2984: addToJSMap(ctx, map) {
...
L4515: function shouldWarn(deprecation) {
L4516: const env = typeof process !== "undefined" && process.env || {};
L4517: if (deprecation) {
...
L5075: handle: "!!",
L5076: prefix: "tag:private.yaml.org,2002:"
L5077: }]
High Trigger Reachable Credential Exfiltration
A manifest entrypoint or package-local install chain reaches credential exfiltration behavior.
dist/lib.js View on unpkg · L42 • Trigger-reachable fixed external POST callback chain: manifest.main -> dist/lib.js
arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0);
if (!ctx) return JSON.stringify(this);
return JSON.stringify(jsKey);
if (!ctx || !ctx.doc) return JSON.stringify(this);
if (!ctx) return JSON.stringify(this);
if (!(item instanceof Pair)) throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`);
// later mapping nodes. -- http://yaml.org/type/merge.html
const json = JSON.stringify(value);
High Trigger Reachable External Post Callback
A manifest entrypoint or package-local install chain reaches a fixed external POST callback.
dist/lib.js View on unpkg • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/lib.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
similarity = 1.000
summary = normalized source hash matched finalized malicious source
43 Trigger-reachable persistence chain: manifest.exports -> dist/index.js
L43: try {
L44: JSON.parse(str);
L45: return true;
...
L2983: // Keys in mapping nodes earlier in the sequence override keys specified in
L2984: // later mapping nodes. -- http://yaml.org/type/merge.html
L2985: addToJSMap(ctx, map) {
...
L4516: function shouldWarn(deprecation) {
L4517: const env = typeof process !== "undefined" && process.env || {};
L4518: if (deprecation) {
...
L5076: handle: "!!",
L5077: prefix: "tag:private.yaml.org,2002:"
L5078: }]
High Trigger Reachable Persistence
A manifest entrypoint or package-local install chain reaches persistence behavior.
dist/index.js View on unpkg · L43 • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/index.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/index.js View on unpkg dist/global-install.js#virtual:string-array:round1 View file • stage = ast_semantic_analysis; reason = ast_parse_error; limitedFiles = 5
High Semantic Analysis Limited
A bounded semantic-analysis stage reached its safety limit; remaining detectors completed, but this package requires AI review.
dist/global-install.js#virtual:string-array:round1 View on unpkg • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/commands/index.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/commands/index.js View on unpkg • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/logs-server.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/logs-server.js View on unpkg • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = hooks/conversation.mjs
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
hooks/conversation.mjs View on unpkg '"$home"/.local/share/fnm/node-versions/*/installation/bin/node'
,
131 '"$home"/Library/Application Support/fnm/node-versions/*/installation/bin/node' ,
133 '"$home"/.volta/tools/image/node/*/bin/node' ,
134 // asdf, old layout and the current plugin one.
135 '"$home"/.asdf/installs/nodejs/*/bin/node' ,
136 '"$home"/.asdf/installs/node/*/bin/node'
138 LAUNCHER_NAME = "sg-run.sh" ;
144 import { execFileSync } from "child_process" ;
145 import { existsSync as existsSync2, readFileSync as readFileSync3, statSync as statSync2 } from "fs" ;
High Child Process
Package source references child process execution.
dist/tui/index.js View on unpkg · L143 146 import { join as join3 } from "path" ;
147 import { homedir as homedir3 } from "os" ;
148 function hookCanStart () {
149 const launcher = join3 ( hooksDir (), LAUNCHER_NAME );
150 if (process.platform === "win32" ) {
151 const ok = existsSync2 (process.execPath);
152 return { ok, node: process.execPath, detail: ok ? process.execPath : `${ process . execPath } is gone` };
154 if ( ! existsSync2 (launcher)) {
155 return { ok: false , detail: "hook launcher missing - run `solongate repair`" };
158 const out = execFileSync ( "/bin/sh" , [launcher, "--sg-doctor" ], {
161 stdio: [ "ignore" , "pipe" , "pipe" ]
163 if ( ! out) return { ok: false , detail: "launcher found no node runtime - set SOLONGATE_NODE or install node" };
, message:
"guard removed (open a new session)"
};
884 const s = JSON . parse ( readFileSync4 (p.settingsPath, "utf-8" ));
886 writeFileSync2 (p.settingsPath, JSON . stringify (s, null , 2 ) + " \n " );
887 return { ok: true , message: "guard removed (open a new session)" };
889 return { ok: false , message: e instanceof Error ? e.message : String (e) };
892 function escapeRe ( s ) {
893 return s. replace ( / [.*+?^${}()|[ \]\\ ] / g , " \\ $&" );
895 function shimTargets () {
896 if (process.platform === "win32" ) {
898 const prof = execFileSync2 ( "powershell" , [ "-NoProfile" , "-Command" , "$PROFILE.CurrentUserAllHosts" ], { encoding: "utf-8" }). trim ();
899 return prof ? [prof] : [];
904 return [ ".bashrc" , ".zshrc" , ".profile" ]. map (( f ) => join4 ( homedir4 (), f)). filter (( f ) => existsSync3 (f));
906 function writeShimBlock ( file , block2 ) {
907 const re = new RegExp ( escapeRe ( SHIM_BEGIN ) + "[ \\ s \\ S]*?" + escapeRe ( SHIM_END ) + " \\ r? \\ n?" , "g" );
908 let content = existsSync3 (file) ? readFileSync4 (file, "utf-8" ) : "" ;
909 content = content. replace (re, "" );
911 if (content. length && ! content. endsWith ( " \n " )) content += " \n " ;
912 content += block2 + " \n " ;
914 mkdirSync ( dirname (file), { recursive: true });
915 writeFileSync2 (file, content);
917 function removeClaudeShim () {
1512 recommendation : "Pin all package versions. Add deny-undeclared-default rule. Add tool allowlist."
1518 status: "NOT_PROTECTED" ,
1520 summary: `${ totalIssues } risky package install(s) detected in logs.` ,
1521 details: "Agents installed packages without pinned versions. A compromised package could inject malicious tools. No tool allowlist blocks unknown tools." ,
1522 recommendation: "Pin all package versions. Add deny-undeclared-default rule. Add tool allowlist."
1526 // src/audit/checks/asi05-code-execution.ts
1527 var DANGEROUS_PATTERNS = [
1528 { pattern: /eval \s * \( / , label: "eval() \u2014 arbitrary code execution" },
1529 { pattern: / \b exec \s * \( / , label: "exec() \u2014 arbitrary code execution" },
1530 { pattern: /python \s + -c \s + ['"] / , label: "python -c inline code execution" },
1531 { pattern: /node \s + -e \s + ['"] / , label: "node -e inline code execution" },
1532 { pattern: /curl \s + . * \| \s * (ba) ? sh/ , label: "curl pipe to shell \u2014 remote code execution" },
1533 { pattern: /wget \s + . * \| \s * (ba) ? sh/ , label: "wget pipe to shell \u2014 remote code execution" },
1534 { pattern: /base64 \s + -d \s * \| / , label: "base64 decode piped to execution" },
1535 { pattern: /powershell \s + -e(ncodedcommand) ? / i , label: "powershell encoded command" }
1537 function checkCodeExecution ( data , deep ) {
1538 const code = "ASI05" ;
1539 const title = "Code Execution" ;
1540 const evidence = [];
1542 let dangerousExec = 0 ;
1543 let noSandbox = true ;
1545 for ( const tc of data.sessions. flatMap (( s ) => s.toolCalls)) {
1546 const toolLower = tc.toolName. toLowerCase ();
1547 const argStr = JSON . stringify (tc.arguments);
• matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = dist/audit/index.js
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
dist/audit/index.js View on unpkg 28 // is no subcommand to delegate, and the proxy-go test that reads this list
29 // enforces that the two halves agree.
31 var GO_INFO_ARGS = /* @__PURE__ */ new Set ([ "login" , "help" , "--help" , "-h" , "--version" , "-v" , "version" ]);
32 var argv = process.argv. slice ( 2 );
33 var first = argv[ 0 ] ?? "" ;
34 var delegable = argv. length === 0 || GO_SUBCOMMANDS . has (first) || GO_INFO_ARGS . has (first);
35 function candidates () {
37 if (process.env. SOLONGATE_CLI_BIN ) out. push (process.env. SOLONGATE_CLI_BIN );
38 const exe = process.platform === "win32" ? "solongate.exe" : "solongate" ;
39 const os_ = process.platform === "win32" ? "win32" : process.platform;
40 const cpu = process.arch === "x64" ? "x64" : process.arch;
42 const req = createRequire ( import . meta .url);
43 out. push ( join ( dirname (req. resolve ( `@solongate/guard-${ os_ }-${ cpu }/package.json` )), exe));
Medium Dynamic Require
Package source references dynamic require/import behavior.
dist/cli-launch.js View on unpkg · L41 46 out. push ( resolve ( homedir (), ".solongate" , "bin" , exe));
50 for ( const bin of candidates ()) {
52 if ( ! existsSync (bin)) continue ;
53 if (process.platform !== "win32" ) accessSync (bin, constants. X_OK );
57 const r = spawnSync (bin, argv, { stdio: "inherit" });
58 if (r.error || r.signal) return null ;
59 if (r.status === 69 ) return null ;
});
271 req. on ( 'error' , () => { try { res. destroy (); } catch { /* ignore */ } });
273 return new Promise (( resolveP ) => {
274 server. listen ( 0 , '127.0.0.1' , () => {
275 const addr = server. address ();
276 resolveP ({ port: addr && typeof addr === 'object' ? addr.port : 0 , close : () => server. close () });
281 async function main () {
282 const sep = process.argv. indexOf ( '--' );
283 const cmd = sep !== - 1 ? process.argv. slice (sep + 1 ) : [];
284 if (cmd. length === 0 ) { log ( 'usage: node shield.mjs -- <command> [args...]' ); process. exit ( 1 ); }
285 const upstream = pickUpstream ();
286 const { port , close } = await startProxy (upstream);
287 const child = spawn (cmd[ 0 ], cmd. slice ( 1 ), {
289 env: { ... process.env, ANTHROPIC_BASE_URL: `http://127.0.0.1:${ port }` },
290 shell: process.platform === 'win32' ,
High Same File Env Network Execution
A single source file combines environment access, network access, and code or shell execution; review context before blocking.
hooks/shield.mjs View on unpkg · L286 292 const shutdown = () => { try { close (); } catch { /* ignore */ } };
293 child. on ( 'exit' , ( code , signal ) => { shutdown (); if (signal) process. kill (process.pid, signal); else process. exit (code ?? 0 ); });
294 child. on ( 'error' , ( e ) => { log ( 'failed to launch command:' , e.message); shutdown (); process. exit ( 1 ); });
295 for ( const sig of [ 'SIGINT' , 'SIGTERM' ]) process. on (sig, () => { try { child. kill (sig); } catch { /* ignore */ } });
• matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = hooks/shield.mjs
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
hooks/shield.mjs View on unpkg 12 * Cloud differences vs. air-gap guard.mjs:
13 * - API_KEY (sg_live_…/sg_test_…) from env/.env, attached to every API call.
14 * - API_URL defaults to https://api.solongate.com.
15 * - Enforcement is gated on the API key (the key identifies the project +
16 * its active policy), NOT on SOLONGATE_AGENT_ID.
17 * - No AI Judge and NO gray route: cloud routing is binary, WHITE (allow) /
18 * BLACK (block). The OPA policy alone decides; nothing is escalated.
20 * Exit code 2 = BLOCK, exit code 0 = ALLOW.
21 * Logs DENY decisions to SolonGate Cloud. ALLOWs are logged by audit.mjs.
22 * Auto-installed by: npx @solongate/proxy init --global
24 import { readFileSync, existsSync, statSync, readdirSync, writeFileSync, mkdirSync, chmodSync, renameSync, appendFileSync, rmSync, rmdirSync, openSync, readSync, closeSync, accessSync, constants } from 'node:fs' ;
25 import { spawn, spawnSync } from 'node:child_process' ;
26 import { resolve, join, dirname, isAbsolute } from 'node:path' ;
27 import { homedir } from 'node:os' ;
28 import { createRequire } from 'node:module' ;
29 import { gunzipSync } from 'node:zlib' ;
30
Critical Credential Exfiltration
Source appears to send environment or credential material to an external endpoint.
hooks/guard.mjs View on unpkg · L13 31 // ── Per-project scratch, kept OUT of the project ─────────────────────────────
32 // The guard and the audit hook pass a few small flags to each other (the eval
33 // ring, the last-eval measurement, the deny flag, the tool-call marker). These
13 * - API_KEY (sg_live_…/sg_test_…) from env/.env, attached to every API call.
L14: * - API_URL defaults to https://api.solongate.com.
L15: * - Enforcement is gated on the API key (the key identifies the project +
...
L19: *
L20: * Exit code 2 = BLOCK, exit code 0 = ALLOW.
L21: * Logs DENY decisions to SolonGate Cloud. ALLOWs are logged by audit.mjs.
...
L24: import { readFileSync, existsSync, statSync, readdirSync, writeFileSync, mkdirSync, chmodSync, renameSync, appendFileSync, rmSync, rmdirSync, openSync, readSync, closeSync, accessS...
L25: import { spawn, spawnSync } from 'node:child_process';
L26: import { resolve, join, dirname, isAbsolute } from 'node:path';
...
L28: import { createRequire } from 'node:module';
L29: import { gunzipSync } from 'node:zlib';
L30:
High Cloud Metadata Access
Source reaches cloud instance metadata or link-local credential endpoints.
hooks/guard.mjs View on unpkg · L13 • matchType = normalized_sha256
matchedPackage = @solongate/proxy@0.89.93
matchedPath = hooks/guard.mjs
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
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.
hooks/guard.mjs View on unpkg • matchType = malicious_source_fingerprint_signature
signature = 2b042aec1906047c
signatureType = suspicious_hashes
sourceLabel = final_verdict:malicious
matchedPackage = @solongate/proxy@0.89.93
matchedPath = hooks/guard.mjs
matchedIdentity = npm:QHNvbG9uZ2F0ZS9wcm94eQ:0.89.93
similarity = 1.000
shingleOverlap = 15
summary = package final verdict is malicious
High Known Malware Source Fingerprint Signature
Source fingerprint signature matches a known malicious package signature; route for source-aware review.
hooks/guard.mjs View on unpkg High
Known Malware Source Similarity
Source file is highly similar to a previously finalized malicious package; route for source-aware review.
dist/lib.js View on unpkg