agentsmesh 0.19.0 → 0.19.1
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/CHANGELOG.md +59 -0
- package/dist/canonical.js +5 -1
- package/dist/canonical.js.map +1 -1
- package/dist/cli.js +135 -135
- package/dist/engine.js +20 -1
- package/dist/engine.js.map +1 -1
- package/dist/index.js +20 -1
- package/dist/index.js.map +1 -1
- package/dist/targets.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.19.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 041b9c5: fix(security): plug input/path/proto-pollution holes in plugin, install, MCP, and config
|
|
8
|
+
|
|
9
|
+
Closes a batch of security audit findings (2 HIGH + 5 MEDIUM):
|
|
10
|
+
- **Plugin source containment** (`src/plugins/load-plugin.ts`) — local plugin
|
|
11
|
+
sources are now resolved with `realpath` and rejected when they escape
|
|
12
|
+
`projectRoot`. A hostile `agentsmesh.yaml` with
|
|
13
|
+
`plugins[].source: "../../tmp/evil.js"` no longer reaches dynamic
|
|
14
|
+
`import()`. Bare npm specifiers continue to resolve through
|
|
15
|
+
`node_modules/<source>`. Both sides are canonicalized so macOS
|
|
16
|
+
`/tmp -> /private/tmp` (and other platform-level symlinks) do not
|
|
17
|
+
produce false positives.
|
|
18
|
+
- **Prototype pollution denylist** (`src/config/core/loader.ts`) —
|
|
19
|
+
`deepMergeObjects` over `agentsmesh.local.yaml` now skips `__proto__`,
|
|
20
|
+
`constructor`, and `prototype` keys. Defense-in-depth: the `yaml` v2
|
|
21
|
+
parser already strips `__proto__`, but this pins the invariant against
|
|
22
|
+
future parser swaps.
|
|
23
|
+
- **Install manifest name validation** (`src/install/core/install-manifest.ts`) —
|
|
24
|
+
`installManifestEntrySchema.name` now refuses path separators, NUL,
|
|
25
|
+
and `.`/`..` segments. A poisoned `installs.yaml` entry can no longer
|
|
26
|
+
drive `rm -rf` outside `.agentsmesh/packs/` at uninstall time.
|
|
27
|
+
- **`git+http://` allowlist** (`src/config/remote/remote-source.ts`) —
|
|
28
|
+
rejected by default; opt-in via `AGENTSMESH_ALLOW_INSECURE_GIT=1` for
|
|
29
|
+
closed-network development. `https://`, `ssh://`, and `file://` are
|
|
30
|
+
unchanged. Closes a MITM window before SHA pinning resolves.
|
|
31
|
+
- **MCP `cwd` / `description` refinement** (`src/mcp/schemas.ts`) — `cwd`
|
|
32
|
+
rejects `..` segments (POSIX + Windows separators), NUL, and newlines;
|
|
33
|
+
`description` rejects NUL and newlines. MCP clients can no longer
|
|
34
|
+
plant a structurally-escaping working directory that downstream agents
|
|
35
|
+
consume via `spawn(command, args, { cwd })`.
|
|
36
|
+
- **Global path redaction in MCP errors** (`src/mcp/errors.ts`) —
|
|
37
|
+
`redactAbsolutePaths` now strips paths anywhere in the string, catching
|
|
38
|
+
embedded paths in stack frames (`at Foo (/Users/...)`) and quoted
|
|
39
|
+
paths in Node errors (`ENOENT, open '/Users/...'`) the prior
|
|
40
|
+
whitespace-anchored regex missed.
|
|
41
|
+
- **`copyDir` symlink hardening** (`src/utils/filesystem/fs-traverse.ts`) —
|
|
42
|
+
`copyDir` now uses `lstat` and skips symlinks. A symlink in the source
|
|
43
|
+
tree pointing outside its root can no longer have its target's bytes
|
|
44
|
+
exfiltrated into the destination (and into any redistributed pack
|
|
45
|
+
built on top of it).
|
|
46
|
+
|
|
47
|
+
Behavioral changes that could affect existing consumers:
|
|
48
|
+
- `git+http://...` extends/installs require `AGENTSMESH_ALLOW_INSECURE_GIT=1`.
|
|
49
|
+
- MCP server entries with `cwd: "../foo"` no longer parse — rewrite as a
|
|
50
|
+
POSIX-relative path without `..` segments.
|
|
51
|
+
- Plugin `source:` entries pointing outside the project tree no longer
|
|
52
|
+
load. The standard `node_modules/<plugin>` and project-local layouts
|
|
53
|
+
are unaffected.
|
|
54
|
+
- A poisoned `installs.yaml` entry whose `name` contains separators or
|
|
55
|
+
`..` is now dropped at parse time (the rest of the manifest survives).
|
|
56
|
+
- A `agentsmesh.local.yaml` payload at `__proto__`, `constructor`, or
|
|
57
|
+
`prototype` keys is silently dropped instead of merged.
|
|
58
|
+
|
|
59
|
+
Branch coverage > 95% on every touched file; full unit/integration suite
|
|
60
|
+
(7596 tests) and plugin e2e suite (57 tests) green.
|
|
61
|
+
|
|
3
62
|
## 0.19.0
|
|
4
63
|
|
|
5
64
|
### Minor Changes
|
package/dist/canonical.js
CHANGED
|
@@ -19044,7 +19044,9 @@ function parseGitSource(source) {
|
|
|
19044
19044
|
} catch {
|
|
19045
19045
|
return null;
|
|
19046
19046
|
}
|
|
19047
|
-
|
|
19047
|
+
const allowInsecure = process.env.AGENTSMESH_ALLOW_INSECURE_GIT === "1" || process.env.AGENTSMESH_ALLOW_INSECURE_GIT === "true";
|
|
19048
|
+
const allowedProtocols = allowInsecure ? ["https:", "http:", "ssh:", "file:"] : ["https:", "ssh:", "file:"];
|
|
19049
|
+
if (!allowedProtocols.includes(parsedUrl.protocol)) {
|
|
19048
19050
|
return null;
|
|
19049
19051
|
}
|
|
19050
19052
|
return { url, ref };
|
|
@@ -20984,10 +20986,12 @@ async function loadConfig(configPath) {
|
|
|
20984
20986
|
}
|
|
20985
20987
|
return result.data;
|
|
20986
20988
|
}
|
|
20989
|
+
var PROTOTYPE_POLLUTION_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
20987
20990
|
function deepMergeObjects(base, overrides2) {
|
|
20988
20991
|
const result = { ...base };
|
|
20989
20992
|
for (const [k, v] of Object.entries(overrides2)) {
|
|
20990
20993
|
if (v === null || v === void 0) continue;
|
|
20994
|
+
if (PROTOTYPE_POLLUTION_KEYS.has(k)) continue;
|
|
20991
20995
|
const baseVal = result[k];
|
|
20992
20996
|
if (typeof v === "object" && !Array.isArray(v) && v !== null && typeof baseVal === "object" && baseVal !== null && !Array.isArray(baseVal)) {
|
|
20993
20997
|
result[k] = deepMergeObjects(
|