@blogic-cz/agent-tools 1.5.0 → 1.5.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.
|
@@ -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;AAM5E,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;AAM5E,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;AA+aF,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,CAqNrF;AAQD,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,UA9qBD,SAAS,UAAU,UAAU,KAAK,IA8qBM,CAAC;AAE5E,oDAAoD;AACpD,eAAO,MAAM,aAAa,YAhrBC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAgrBjB,CAAC;AAExD,yEAAyE;AACzE,eAAO,MAAM,aAAa,aAlrBE,MAAM,KAAK,OAkrBgB,CAAC;AAExD,yDAAyD;AACzD,eAAO,MAAM,aAAa,aAprBE,MAAM,KAAK,OAorBgB,CAAC;AAExD,oEAAoE;AACpE,eAAO,MAAM,sBAAsB,YAtrBC,MAAM,KAAK,OAsrB0B,CAAC;AAE1E,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,YAxrBC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAwrBf,CAAC;AAEhE,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,YA1rBC,MAAM,KAAK,OA0rBsB,CAAC;AAElE,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,YA5rBC,MAAM,KAAK,MAAM,GAAG,IA4rBa,CAAC"}
|
package/package.json
CHANGED
|
@@ -312,13 +312,57 @@ function parseStaticShellCommands(
|
|
|
312
312
|
}
|
|
313
313
|
|
|
314
314
|
function mentionsEnvironmentRead(text: string): boolean {
|
|
315
|
-
|
|
315
|
+
// `--env dev` is a flag of another command, not the env command.
|
|
316
|
+
return /printenv|(?<!--)\benv\b/i.test(text.replace(/['"\\]/g, ""));
|
|
316
317
|
}
|
|
317
318
|
|
|
318
319
|
function hasBraceExpansion(text: string): boolean {
|
|
319
320
|
return /\{[^{}]*(?:,|\.\.)[^{}]*\}/.test(text);
|
|
320
321
|
}
|
|
321
322
|
|
|
323
|
+
/**
|
|
324
|
+
* The command without quoted regex quantifiers such as `{0,80}`. Many commands re-parse quoted
|
|
325
|
+
* text as shell code, so every other quoted brace stays. When both sides are digits, the expansion
|
|
326
|
+
* cannot spell a command name. An empty side is not safe: `e{,}nv` and `e{0,}nv` expand to `env`.
|
|
327
|
+
* An unclosed quote keeps the raw command.
|
|
328
|
+
*/
|
|
329
|
+
function withoutQuotedQuantifiers(command: string): string {
|
|
330
|
+
let text = "";
|
|
331
|
+
let quote: "'" | '"' | "$'" | undefined;
|
|
332
|
+
for (let i = 0; i < command.length; i++) {
|
|
333
|
+
const char = command.charAt(i);
|
|
334
|
+
const quantifier = quote ? /^\{\d+,\d+\}/.exec(command.slice(i))?.[0] : undefined;
|
|
335
|
+
if (quantifier) {
|
|
336
|
+
i += quantifier.length - 1;
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
text += char;
|
|
340
|
+
if (quote === "'") {
|
|
341
|
+
if (char === "'") quote = undefined;
|
|
342
|
+
} else if (char === "\\") {
|
|
343
|
+
text += command[++i] ?? "";
|
|
344
|
+
} else if (quote) {
|
|
345
|
+
if (char === quote.at(-1)) quote = undefined;
|
|
346
|
+
} else if (char === "$" && command[i + 1] === "'") {
|
|
347
|
+
quote = "$'";
|
|
348
|
+
text += command[++i];
|
|
349
|
+
} else if (char === "'" || char === '"') {
|
|
350
|
+
quote = char;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return quote ? command : text;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/** Braces in static words, except `{m,n}` with digits on both sides (see above). */
|
|
357
|
+
function hasArgumentBraceExpansion(text: string): boolean {
|
|
358
|
+
return hasBraceExpansion(text.replace(/\{\d+,\d+\}/g, ""));
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/** echo and printf print their arguments; grep -o, rg and git grep print matched pattern text. */
|
|
362
|
+
function isLiteralTextProducer(argv: string[]): boolean {
|
|
363
|
+
return isPassiveTextCommand(argv) && argv[0]?.split("/").at(-1) !== "head";
|
|
364
|
+
}
|
|
365
|
+
|
|
322
366
|
function unwrapStaticCommand(words: string[]): string[] {
|
|
323
367
|
const argv = [...words];
|
|
324
368
|
const executable = () => argv[0]?.split("/").at(-1);
|
|
@@ -369,17 +413,10 @@ function hasStaticEnvironmentRead(argv: string[], allowedNames: Set<string>): bo
|
|
|
369
413
|
if (name === "printenv") return !isAllowedEnvironmentRead(argv, allowedNames);
|
|
370
414
|
if (name === "env") return true;
|
|
371
415
|
if (isPassiveTextCommand(argv)) return false;
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
),
|
|
377
|
-
) &&
|
|
378
|
-
hasBraceExpansion(argv.slice(1).join(" "))
|
|
379
|
-
) {
|
|
380
|
-
return true;
|
|
381
|
-
}
|
|
382
|
-
return mentionsEnvironmentRead(argv.join(" "));
|
|
416
|
+
// Any command may re-parse an argument as shell code (trap, find -exec, awk system()).
|
|
417
|
+
return (
|
|
418
|
+
hasArgumentBraceExpansion(argv.slice(1).join(" ")) || mentionsEnvironmentRead(argv.join(" "))
|
|
419
|
+
);
|
|
383
420
|
}
|
|
384
421
|
|
|
385
422
|
function hasEnvironmentRead(command: string, allowedNames: Set<string>): boolean {
|
|
@@ -387,7 +424,9 @@ function hasEnvironmentRead(command: string, allowedNames: Set<string>): boolean
|
|
|
387
424
|
// ponytail: complex shell syntax stays conservative; use a shell AST if more exceptions are needed.
|
|
388
425
|
const parsed = parseStaticShellCommands(command);
|
|
389
426
|
if (parsed === "brace-expansion") return true;
|
|
390
|
-
if (!parsed)
|
|
427
|
+
if (!parsed) {
|
|
428
|
+
return mentionsEnvironmentRead(command) || hasBraceExpansion(withoutQuotedQuantifiers(command));
|
|
429
|
+
}
|
|
391
430
|
const pipelines = parsed.pipelines.map((commands) => commands.map(unwrapStaticCommand));
|
|
392
431
|
const unwrapped = pipelines.flat();
|
|
393
432
|
if (unwrapped.some((argv) => hasStaticEnvironmentRead(argv, allowedNames))) return true;
|
|
@@ -399,8 +438,8 @@ function hasEnvironmentRead(command: string, allowedNames: Set<string>): boolean
|
|
|
399
438
|
pipeline.some(
|
|
400
439
|
(argv) =>
|
|
401
440
|
isAllowedEnvironmentRead(argv, allowedNames) ||
|
|
402
|
-
(
|
|
403
|
-
(mentionsEnvironmentRead(argv.join(" ")) ||
|
|
441
|
+
(isLiteralTextProducer(argv) &&
|
|
442
|
+
(mentionsEnvironmentRead(argv.join(" ")) || hasArgumentBraceExpansion(argv.join(" ")))),
|
|
404
443
|
) &&
|
|
405
444
|
pipeline.some(
|
|
406
445
|
(argv) => !isPassiveTextCommand(argv) && !isAllowedEnvironmentRead(argv, allowedNames),
|