@blogic-cz/agent-tools 1.6.10 → 1.6.11
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/README.md
CHANGED
|
@@ -654,7 +654,7 @@ Claude Code uses shell command hooks. The package ships a ready-made wrapper scr
|
|
|
654
654
|
|
|
655
655
|
That's it. The hook reads tool input from stdin, runs the guard, and exits with code 2 (blocked + reason on stderr) or 0 (allowed).
|
|
656
656
|
|
|
657
|
-
The guard permits static `printenv` reads and simple `echo`/`printf` expansions only for exact names in `credentialGuard.allowedEnvironmentVariables`. The default list is empty. Multiple names are allowed only when each name is approved. Approved environment values may be displayed, but redirecting their pipeline or passing them to an executor stays blocked.
|
|
657
|
+
The guard permits static `printenv` reads and simple `echo`/`printf` expansions only for exact names in `credentialGuard.allowedEnvironmentVariables`. Quoted empty defaults such as `"${NAME:-}"` follow the same display rules, including `printf` data arguments with a literal format; unquoted defaults, nonempty defaults, and other parameter operators stay blocked. The default list is empty. Multiple names are allowed only when each name is approved. Approved environment values may be displayed, but redirecting their pipeline or passing them to an executor stays blocked.
|
|
658
658
|
|
|
659
659
|
Python inline programs and quoted stdin heredocs can also display approved values through `os.getenv("NAME")`, `os.environ.get("NAME", "default")`, or `os.environ["NAME"]`. The complete program must import unaliased `os`, plus `json` for JSON display, followed by `print(...)` statements. `json.dumps(...)` supports dictionaries and lists of approved reads, including comprehensions over a nonempty literal list of approved names. Every dictionary key and environment read must use an approved name. Each projection has at most 16 entries; the program has at most 65,536 characters. Computed or unbounded names, aliases, escaped or interpolated strings, additional statements, and whole-environment output remain unsupported. The same redirection and pipeline restrictions apply.
|
|
660
660
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credential-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAmB,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAK5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAM/D,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,CAAC;AAQF,+CAA+C;AAC/C,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACxE,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3E,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjF,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACjD,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACxD,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credential-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAmB,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAK5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAM/D,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,CAAC;AAQF,+CAA+C;AAC/C,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACxE,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3E,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjF,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACjD,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACxD,CAAC;AA2uFF,6CAA6C;AAC7C,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAErE;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAMD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,qBAAqB,GAAG,eAAe,CA4VrF;AAQD,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,UAjnGD,SAAS,UAAU,UAAU,KAAK,IAinGM,CAAC;AAE5E,oDAAoD;AACpD,eAAO,MAAM,aAAa,YAnnGC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAmnGjB,CAAC;AAExD,yEAAyE;AACzE,eAAO,MAAM,aAAa,aArnGE,MAAM,KAAK,OAqnGgB,CAAC;AAExD,yDAAyD;AACzD,eAAO,MAAM,aAAa,aAvnGE,MAAM,KAAK,OAunGgB,CAAC;AAExD,oEAAoE;AACpE,eAAO,MAAM,sBAAsB,YAznGC,MAAM,KAAK,OAynG0B,CAAC;AAE1E,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,YA3nGC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IA2nGf,CAAC;AAEhE,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,YA7nGC,MAAM,KAAK,OA6nGsB,CAAC;AAElE,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,YA/nGC,MAAM,KAAK,MAAM,GAAG,IA+nGa,CAAC"}
|
package/package.json
CHANGED
|
@@ -2552,7 +2552,7 @@ function hasEnvironmentVariableExpansionRead(
|
|
|
2552
2552
|
const name = variable[1] ?? variable[3] ?? "";
|
|
2553
2553
|
if (variable[2]) {
|
|
2554
2554
|
if (quote !== '"' || !allowedNames.has(name)) invalidExpansion = true;
|
|
2555
|
-
normalized += "
|
|
2555
|
+
normalized += "ENVVALUE";
|
|
2556
2556
|
i += variable[0].length - 1;
|
|
2557
2557
|
continue;
|
|
2558
2558
|
}
|
|
@@ -2606,13 +2606,6 @@ function hasEnvironmentVariableExpansionRead(
|
|
|
2606
2606
|
)
|
|
2607
2607
|
return true;
|
|
2608
2608
|
}
|
|
2609
|
-
for (const words of parsed.pipelines.flat()) {
|
|
2610
|
-
if (
|
|
2611
|
-
words.some((arg) => arg.includes("ENVTESTVALUE")) &&
|
|
2612
|
-
!isApprovedEnvironmentPredicate(unwrapStaticCommand(words))
|
|
2613
|
-
)
|
|
2614
|
-
return true;
|
|
2615
|
-
}
|
|
2616
2609
|
for (const words of parsed.pipelines.flat()) {
|
|
2617
2610
|
if (!words.some((arg) => arg.includes("UNKNOWNVALUE"))) continue;
|
|
2618
2611
|
if (words.some((arg) => arg.includes("UNKNOWNVALUEUNQUOTED"))) return true;
|
|
@@ -2623,7 +2616,7 @@ function hasEnvironmentVariableExpansionRead(
|
|
|
2623
2616
|
)
|
|
2624
2617
|
return true;
|
|
2625
2618
|
}
|
|
2626
|
-
if (!localMaterialized.includes("ENVVALUE")
|
|
2619
|
+
if (!localMaterialized.includes("ENVVALUE")) {
|
|
2627
2620
|
return (
|
|
2628
2621
|
hasSensitiveFileRead(localMaterialized, isPathBlocked) ||
|
|
2629
2622
|
hasSensitivePathRedirect(localMaterialized, isPathBlocked) ||
|
|
@@ -2633,7 +2626,7 @@ function hasEnvironmentVariableExpansionRead(
|
|
|
2633
2626
|
|
|
2634
2627
|
for (const [index, pipeline] of parsed.pipelines.entries()) {
|
|
2635
2628
|
const hasEnvironmentValue = pipeline.some((argv) =>
|
|
2636
|
-
argv.some((arg) => arg.includes("ENVVALUE")
|
|
2629
|
+
argv.some((arg) => arg.includes("ENVVALUE")),
|
|
2637
2630
|
);
|
|
2638
2631
|
if (!hasEnvironmentValue) continue;
|
|
2639
2632
|
if (parsed.redirects.some((redirect) => redirect.pipeline === index)) return true;
|
|
@@ -2641,12 +2634,8 @@ function hasEnvironmentVariableExpansionRead(
|
|
|
2641
2634
|
pipeline.some((argv) => {
|
|
2642
2635
|
const unwrapped = unwrapStaticCommand(argv);
|
|
2643
2636
|
const name = unwrapped[0]?.split("/").at(-1) ?? "";
|
|
2644
|
-
if (argv.some((arg) => arg.includes("ENVVALUE")
|
|
2645
|
-
if (
|
|
2646
|
-
argv
|
|
2647
|
-
.slice(0, argv.length - unwrapped.length)
|
|
2648
|
-
.some((arg) => arg.includes("ENVVALUE") || arg.includes("ENVTESTVALUE"))
|
|
2649
|
-
)
|
|
2637
|
+
if (argv.some((arg) => arg.includes("ENVVALUE"))) {
|
|
2638
|
+
if (argv.slice(0, argv.length - unwrapped.length).some((arg) => arg.includes("ENVVALUE")))
|
|
2650
2639
|
return true;
|
|
2651
2640
|
if (isApprovedEnvironmentPredicate(unwrapped)) return false;
|
|
2652
2641
|
if (isNavigationOperand(unwrapped, "ENVVALUE")) {
|
|
@@ -2682,7 +2671,7 @@ function isApprovedEnvironmentPredicate(argv: string[]): boolean {
|
|
|
2682
2671
|
if (args.at(-1) !== "]") return false;
|
|
2683
2672
|
args = args.slice(0, -1);
|
|
2684
2673
|
} else if (argv[0] !== "test") return false;
|
|
2685
|
-
const value = (arg: string | undefined) => arg === "ENVVALUE"
|
|
2674
|
+
const value = (arg: string | undefined) => arg === "ENVVALUE";
|
|
2686
2675
|
const literal = (arg: string | undefined) =>
|
|
2687
2676
|
/^[A-Za-z0-9_.:-]*$/.test(arg ?? "") && arg !== undefined;
|
|
2688
2677
|
return (
|