@danypops/vehicle-core 0.18.2 → 0.18.3

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.
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Guards against the argv-injection class behind a well-known family of CLI-wrapper CVEs
3
+ * (simple-git's own history includes several): a caller-influenced string that starts with `-`
4
+ * can be parsed by the target CLI as a *flag* (`--upload-pack`, `--exec`, `--template`, `-c`
5
+ * config override) instead of the literal ref/path/pattern value the caller intended. Any Vehicle
6
+ * operation that hands a caller-supplied string to a shelled-out CLI's argv should run it through
7
+ * this check first, at the exact position it reaches that argv.
8
+ *
9
+ * This is a hard rejection with no exceptions -- it has no opinion about *why* a value starting
10
+ * with `-` might be needed and does not attempt to allow-list specific flags. A caller whose CLI
11
+ * genuinely accepts caller-influenced flag-shaped arguments needs a purpose-built allow-list of
12
+ * its own; this primitive only ever covers the common case of a value that should always be a
13
+ * literal.
14
+ */
15
+ export declare class UnsafeCliArgument extends Error {
16
+ readonly value: string;
17
+ readonly fieldName?: string | undefined;
18
+ constructor(value: string, fieldName?: string | undefined);
19
+ }
20
+ /** Throws UnsafeCliArgument if `value` starts with `-`. `fieldName`, when given, names the field in the thrown error's own message for a caller with several distinct argv positions to check. */
21
+ export declare function assertNoLeadingFlagChar(value: string, fieldName?: string): void;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Guards against the argv-injection class behind a well-known family of CLI-wrapper CVEs
3
+ * (simple-git's own history includes several): a caller-influenced string that starts with `-`
4
+ * can be parsed by the target CLI as a *flag* (`--upload-pack`, `--exec`, `--template`, `-c`
5
+ * config override) instead of the literal ref/path/pattern value the caller intended. Any Vehicle
6
+ * operation that hands a caller-supplied string to a shelled-out CLI's argv should run it through
7
+ * this check first, at the exact position it reaches that argv.
8
+ *
9
+ * This is a hard rejection with no exceptions -- it has no opinion about *why* a value starting
10
+ * with `-` might be needed and does not attempt to allow-list specific flags. A caller whose CLI
11
+ * genuinely accepts caller-influenced flag-shaped arguments needs a purpose-built allow-list of
12
+ * its own; this primitive only ever covers the common case of a value that should always be a
13
+ * literal.
14
+ */
15
+ export class UnsafeCliArgument extends Error {
16
+ value;
17
+ fieldName;
18
+ constructor(value, fieldName) {
19
+ super(fieldName
20
+ ? `"${value}" cannot be used as ${fieldName} -- it would be interpreted as a CLI flag, not a literal value`
21
+ : `"${value}" cannot be used as a CLI argument -- it would be interpreted as a flag, not a literal value`);
22
+ this.value = value;
23
+ this.fieldName = fieldName;
24
+ this.name = "UnsafeCliArgument";
25
+ }
26
+ }
27
+ /** Throws UnsafeCliArgument if `value` starts with `-`. `fieldName`, when given, names the field in the thrown error's own message for a caller with several distinct argv positions to check. */
28
+ export function assertNoLeadingFlagChar(value, fieldName) {
29
+ if (value.startsWith("-"))
30
+ throw new UnsafeCliArgument(value, fieldName);
31
+ }
@@ -0,0 +1 @@
1
+ export * from "./assert-no-leading-flag-char.js";
@@ -0,0 +1 @@
1
+ export * from "./assert-no-leading-flag-char.js";
package/dist/index.d.ts CHANGED
@@ -6,13 +6,15 @@
6
6
  * classification, invocation context), events, manifest, client (the port a
7
7
  * caller programs against), approvals (the Approval Gate's wire shapes), jobs
8
8
  * (Vehicle Jobs' pure pieces), schedules, watches, persistence (atomic
9
- * JSON), and concurrency (timer-based scheduling primitives) -- the latter
10
- * two are technical utilities, not Vehicle protocol capabilities, kept
11
- * distinct for that reason. Every symbol below is re-exported unchanged
9
+ * JSON), concurrency (timer-based scheduling primitives), and cli-safety
10
+ * (argv-injection guards for any operation shelling out to a CLI) -- the
11
+ * latter three are technical utilities, not Vehicle protocol capabilities,
12
+ * kept distinct for that reason. Every symbol below is re-exported unchanged
12
13
  * from its historical flat-file home, so root-level `import { X } from
13
14
  * "@danypops/vehicle-core"` usage is completely unaffected by this layout.
14
15
  */
15
16
  export * from "./approvals/index.js";
17
+ export * from "./cli-safety/index.js";
16
18
  export * from "./client/index.js";
17
19
  export * from "./concurrency/index.js";
18
20
  export * from "./content/index.js";
package/dist/index.js CHANGED
@@ -6,13 +6,15 @@
6
6
  * classification, invocation context), events, manifest, client (the port a
7
7
  * caller programs against), approvals (the Approval Gate's wire shapes), jobs
8
8
  * (Vehicle Jobs' pure pieces), schedules, watches, persistence (atomic
9
- * JSON), and concurrency (timer-based scheduling primitives) -- the latter
10
- * two are technical utilities, not Vehicle protocol capabilities, kept
11
- * distinct for that reason. Every symbol below is re-exported unchanged
9
+ * JSON), concurrency (timer-based scheduling primitives), and cli-safety
10
+ * (argv-injection guards for any operation shelling out to a CLI) -- the
11
+ * latter three are technical utilities, not Vehicle protocol capabilities,
12
+ * kept distinct for that reason. Every symbol below is re-exported unchanged
12
13
  * from its historical flat-file home, so root-level `import { X } from
13
14
  * "@danypops/vehicle-core"` usage is completely unaffected by this layout.
14
15
  */
15
16
  export * from "./approvals/index.js";
17
+ export * from "./cli-safety/index.js";
16
18
  export * from "./client/index.js";
17
19
  export * from "./concurrency/index.js";
18
20
  export * from "./content/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danypops/vehicle-core",
3
- "version": "0.18.2",
3
+ "version": "0.18.3",
4
4
  "description": "Vehicle's runtime-neutral wire contract: operation descriptors, schema codecs, failure shapes. Zero runtime dependencies, zero Bun-specific code -- the one thing every Vehicle client and server package depends on.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Guards against the argv-injection class behind a well-known family of CLI-wrapper CVEs
3
+ * (simple-git's own history includes several): a caller-influenced string that starts with `-`
4
+ * can be parsed by the target CLI as a *flag* (`--upload-pack`, `--exec`, `--template`, `-c`
5
+ * config override) instead of the literal ref/path/pattern value the caller intended. Any Vehicle
6
+ * operation that hands a caller-supplied string to a shelled-out CLI's argv should run it through
7
+ * this check first, at the exact position it reaches that argv.
8
+ *
9
+ * This is a hard rejection with no exceptions -- it has no opinion about *why* a value starting
10
+ * with `-` might be needed and does not attempt to allow-list specific flags. A caller whose CLI
11
+ * genuinely accepts caller-influenced flag-shaped arguments needs a purpose-built allow-list of
12
+ * its own; this primitive only ever covers the common case of a value that should always be a
13
+ * literal.
14
+ */
15
+ export class UnsafeCliArgument extends Error {
16
+ constructor(
17
+ readonly value: string,
18
+ readonly fieldName?: string,
19
+ ) {
20
+ super(
21
+ fieldName
22
+ ? `"${value}" cannot be used as ${fieldName} -- it would be interpreted as a CLI flag, not a literal value`
23
+ : `"${value}" cannot be used as a CLI argument -- it would be interpreted as a flag, not a literal value`,
24
+ );
25
+ this.name = "UnsafeCliArgument";
26
+ }
27
+ }
28
+
29
+ /** Throws UnsafeCliArgument if `value` starts with `-`. `fieldName`, when given, names the field in the thrown error's own message for a caller with several distinct argv positions to check. */
30
+ export function assertNoLeadingFlagChar(value: string, fieldName?: string): void {
31
+ if (value.startsWith("-")) throw new UnsafeCliArgument(value, fieldName);
32
+ }
@@ -0,0 +1 @@
1
+ export * from "./assert-no-leading-flag-char.js";
package/src/index.ts CHANGED
@@ -6,13 +6,15 @@
6
6
  * classification, invocation context), events, manifest, client (the port a
7
7
  * caller programs against), approvals (the Approval Gate's wire shapes), jobs
8
8
  * (Vehicle Jobs' pure pieces), schedules, watches, persistence (atomic
9
- * JSON), and concurrency (timer-based scheduling primitives) -- the latter
10
- * two are technical utilities, not Vehicle protocol capabilities, kept
11
- * distinct for that reason. Every symbol below is re-exported unchanged
9
+ * JSON), concurrency (timer-based scheduling primitives), and cli-safety
10
+ * (argv-injection guards for any operation shelling out to a CLI) -- the
11
+ * latter three are technical utilities, not Vehicle protocol capabilities,
12
+ * kept distinct for that reason. Every symbol below is re-exported unchanged
12
13
  * from its historical flat-file home, so root-level `import { X } from
13
14
  * "@danypops/vehicle-core"` usage is completely unaffected by this layout.
14
15
  */
15
16
  export * from "./approvals/index.js";
17
+ export * from "./cli-safety/index.js";
16
18
  export * from "./client/index.js";
17
19
  export * from "./concurrency/index.js";
18
20
  export * from "./content/index.js";