@solongate/proxy 0.25.4 → 0.25.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -420,7 +420,7 @@ function isAlreadyProtected(server) {
420
420
  if (server.command === "@solongate/proxy") return true;
421
421
  for (const arg of args) {
422
422
  if (arg === "-y" || arg === "--yes") continue;
423
- if (arg === "@solongate/proxy" || arg === "solongate-proxy") return true;
423
+ if (arg === "@solongate/proxy" || arg === "@solongate/proxy@latest" || arg === "solongate-proxy") return true;
424
424
  if (/[/\\]packages[/\\]proxy[/\\]dist[/\\]index\.js$/.test(arg)) return true;
425
425
  break;
426
426
  }
@@ -429,7 +429,7 @@ function isAlreadyProtected(server) {
429
429
  function wrapServer(server, policy) {
430
430
  const env = { ...server.env ?? {} };
431
431
  env.SOLONGATE_API_KEY = "${SOLONGATE_API_KEY}";
432
- const proxyArgs = ["-y", "@solongate/proxy"];
432
+ const proxyArgs = ["-y", "@solongate/proxy@latest"];
433
433
  if (policy) {
434
434
  proxyArgs.push("--policy", policy);
435
435
  }
@@ -6148,17 +6148,26 @@ DENY if the tool call could, directly or indirectly:
6148
6148
  - Read, display, copy, move, or exfiltrate any protected file \u2014 even through:
6149
6149
  - Shell glob patterns (e.g., "cred*" could match "credentials.json")
6150
6150
  - Command substitution ($(...), backticks)
6151
- - Variable interpolation or string concatenation
6151
+ - Process substitution (<(cat file), <(command file)) \u2014 ALWAYS check inside <(...) for protected files
6152
+ - Variable interpolation or string concatenation (e.g., f=".en"; cat ${f}v builds ".env")
6153
+ - Partial variable construction \u2014 if shell variables are concatenated to form a filename, analyze the RESULT
6152
6154
  - Input redirection (< file)
6153
6155
  - Script files that might read protected files
6154
6156
  - Find/exec patterns
6155
- - Any Unix/Windows utility that reads file content (cat, head, tail, less, more, type, perl, awk, sed, sort, diff, comm, paste, tee, xxd, od, strings, dd, tr, etc.)
6157
+ - Multi-stage operations: if command A archives/copies a protected file and command B reads the copy, DENY the ENTIRE chain (e.g., "tar czf /tmp/x.tgz .env && tar xzf /tmp/x.tgz -O")
6158
+ - Any Unix/Windows utility that reads file content (cat, head, tail, less, more, type, perl, awk, sed, sort, diff, comm, paste, tee, xxd, od, strings, dd, tr, tar, zip, etc.)
6156
6159
  - Delete, modify, or overwrite any protected file or path
6157
6160
  - Send data to external URLs, webhooks, or attacker-controlled endpoints
6158
6161
  - Execute remotely downloaded code (curl|bash, wget|sh, etc.)
6159
6162
  - Leak environment variables (printenv, env, /proc/self/environ, npm run env, process.env)
6160
6163
  - Create scripts that bypass security controls
6161
6164
 
6165
+ CRITICAL patterns to watch for:
6166
+ - <(cat .env) or <(cat ANYPROTECTEDFILE) \u2014 process substitution ALWAYS reads the file
6167
+ - Compound commands with && or ; where ANY part touches a protected file \u2014 DENY the whole thing
6168
+ - Variable tricks like f=".en"; cat ${f}v \u2014 mentally evaluate the variable to see if it resolves to a protected filename
6169
+ - tar/zip/cp that archives a protected file, even if the second command reads the archive \u2014 DENY both
6170
+
6162
6171
  ALLOW if:
6163
6172
  - The action is a normal development operation (ls, git status, npm build, etc.)
6164
6173
  - The action does not touch any protected file or path
@@ -6921,7 +6930,7 @@ ${msg.content.text}`;
6921
6930
  if (rule.effect === "DENY" && rule.enabled !== false) {
6922
6931
  const denied = rule.filenameConstraints?.denied;
6923
6932
  if (denied) {
6924
- for (const f of denied) files.add(f);
6933
+ for (const f2 of denied) files.add(f2);
6925
6934
  }
6926
6935
  }
6927
6936
  }
package/dist/init.js CHANGED
@@ -60,7 +60,7 @@ function isAlreadyProtected(server) {
60
60
  if (server.command === "@solongate/proxy") return true;
61
61
  for (const arg of args) {
62
62
  if (arg === "-y" || arg === "--yes") continue;
63
- if (arg === "@solongate/proxy" || arg === "solongate-proxy") return true;
63
+ if (arg === "@solongate/proxy" || arg === "@solongate/proxy@latest" || arg === "solongate-proxy") return true;
64
64
  if (/[/\\]packages[/\\]proxy[/\\]dist[/\\]index\.js$/.test(arg)) return true;
65
65
  break;
66
66
  }
@@ -69,7 +69,7 @@ function isAlreadyProtected(server) {
69
69
  function wrapServer(server, policy) {
70
70
  const env = { ...server.env ?? {} };
71
71
  env.SOLONGATE_API_KEY = "${SOLONGATE_API_KEY}";
72
- const proxyArgs = ["-y", "@solongate/proxy"];
72
+ const proxyArgs = ["-y", "@solongate/proxy@latest"];
73
73
  if (policy) {
74
74
  proxyArgs.push("--policy", policy);
75
75
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.25.4",
3
+ "version": "0.25.6",
4
4
  "description": "MCP security proxy — protect any MCP server with customizable policies, path/command constraints, rate limiting, and audit logging. Zero code changes required.",
5
5
  "type": "module",
6
6
  "bin": {