@wrongstack/core 0.277.0 → 0.277.2
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/defaults/index.js +81 -40
- package/dist/defaults/index.js.map +1 -1
- package/dist/index.js +81 -40
- package/dist/index.js.map +1 -1
- package/dist/security/index.js +90 -49
- package/dist/security/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29606,19 +29606,51 @@ var LruCache = class {
|
|
|
29606
29606
|
// src/security/permission-policy.ts
|
|
29607
29607
|
init_safe_json();
|
|
29608
29608
|
init_tool_subject();
|
|
29609
|
-
var
|
|
29610
|
-
/\
|
|
29611
|
-
|
|
29612
|
-
/\
|
|
29613
|
-
|
|
29614
|
-
/\
|
|
29615
|
-
|
|
29616
|
-
/\
|
|
29617
|
-
|
|
29618
|
-
|
|
29609
|
+
var CATASTROPHIC_PATTERNS = [
|
|
29610
|
+
/\b(?:mkfs(?:\.[a-z0-9]+)?|mke2fs|newfs)\b/i,
|
|
29611
|
+
// make a filesystem — wipes a partition
|
|
29612
|
+
/\bformat\s+[A-Za-z]:/i,
|
|
29613
|
+
// format C: — wipes a Windows volume
|
|
29614
|
+
/\bdiskpart\b/i,
|
|
29615
|
+
// Windows partition editor
|
|
29616
|
+
/\bdd\b[^|]*\bof=(?:\/dev\/|\\\\[.?]\\)/i,
|
|
29617
|
+
// dd writing straight to a raw device
|
|
29618
|
+
/>\s*\/dev\/(?:sd|hd|nvme|disk|mapper|vd)/i,
|
|
29619
|
+
// redirect into a raw block device
|
|
29620
|
+
/:\(\)\s*\{\s*:\|:&\s*\}\s*;/
|
|
29621
|
+
// classic fork bomb
|
|
29619
29622
|
];
|
|
29620
|
-
var
|
|
29621
|
-
|
|
29623
|
+
var CATASTROPHIC_POSIX_ROOTS = /* @__PURE__ */ new Set([
|
|
29624
|
+
"/etc",
|
|
29625
|
+
"/usr",
|
|
29626
|
+
"/bin",
|
|
29627
|
+
"/sbin",
|
|
29628
|
+
"/lib",
|
|
29629
|
+
"/lib64",
|
|
29630
|
+
"/var",
|
|
29631
|
+
"/boot",
|
|
29632
|
+
"/dev",
|
|
29633
|
+
"/sys",
|
|
29634
|
+
"/proc",
|
|
29635
|
+
"/opt",
|
|
29636
|
+
"/root",
|
|
29637
|
+
"/home",
|
|
29638
|
+
"/srv",
|
|
29639
|
+
"/run",
|
|
29640
|
+
"/system",
|
|
29641
|
+
"/library",
|
|
29642
|
+
"/applications",
|
|
29643
|
+
"/users"
|
|
29644
|
+
]);
|
|
29645
|
+
var CATASTROPHIC_WIN_SUBDIRS = /* @__PURE__ */ new Set([
|
|
29646
|
+
"windows",
|
|
29647
|
+
"system32",
|
|
29648
|
+
"winnt",
|
|
29649
|
+
"program files",
|
|
29650
|
+
"program files (x86)",
|
|
29651
|
+
"programdata",
|
|
29652
|
+
"users"
|
|
29653
|
+
]);
|
|
29622
29654
|
var SHELL_OPERATORS = /* @__PURE__ */ new Set(["&&", "||", "|", ";", ">", ">>", "<", "2>", "2>>"]);
|
|
29623
29655
|
function getInputString(input, key) {
|
|
29624
29656
|
if (!input || typeof input !== "object") return void 0;
|
|
@@ -29635,20 +29667,21 @@ function pathLooksInsideProject(rawPath, projectRoot) {
|
|
|
29635
29667
|
function tokenizeShell(command) {
|
|
29636
29668
|
return command.match(/"[^"]*"|'[^']*'|\S+/g)?.map((token) => token.replace(/^['"]|['"]$/g, "")) ?? [];
|
|
29637
29669
|
}
|
|
29638
|
-
function
|
|
29639
|
-
|
|
29640
|
-
if (
|
|
29641
|
-
if (
|
|
29642
|
-
|
|
29643
|
-
if (
|
|
29670
|
+
function isCatastrophicDeleteTarget(rawTarget) {
|
|
29671
|
+
const t2 = rawTarget.replace(/^['"]|['"]$/g, "").trim();
|
|
29672
|
+
if (!t2) return false;
|
|
29673
|
+
if (t2 === "*" || t2 === "." || t2 === "./" || t2 === ".\\" || t2 === "./*" || t2 === ".\\*") return true;
|
|
29674
|
+
const s = t2.replace(/[\\/]\*+$/, "").replace(/[\\/]+$/, "");
|
|
29675
|
+
if (s === "") return true;
|
|
29676
|
+
if (s === "~" || /^\$HOME$/i.test(s) || /^%USERPROFILE%$/i.test(s)) return true;
|
|
29677
|
+
if (/^[A-Za-z]:$/.test(s)) return true;
|
|
29678
|
+
const norm = s.toLowerCase().replace(/\\/g, "/");
|
|
29679
|
+
if (CATASTROPHIC_POSIX_ROOTS.has(norm)) return true;
|
|
29680
|
+
const win = norm.match(/^[a-z]:\/([^/]+)$/);
|
|
29681
|
+
if (win?.[1] && CATASTROPHIC_WIN_SUBDIRS.has(win[1])) return true;
|
|
29644
29682
|
return false;
|
|
29645
29683
|
}
|
|
29646
|
-
function
|
|
29647
|
-
const targets = tokens.slice(start).filter((token) => !token.startsWith("-") && !SHELL_OPERATORS.has(token));
|
|
29648
|
-
if (targets.length === 0) return true;
|
|
29649
|
-
return targets.some((target) => pathTokenIsOutsideProject(target, projectRoot));
|
|
29650
|
-
}
|
|
29651
|
-
function hasDestructiveDelete(command, projectRoot) {
|
|
29684
|
+
function hasCatastrophicDelete(command) {
|
|
29652
29685
|
const tokens = tokenizeShell(command);
|
|
29653
29686
|
for (let i = 0; i < tokens.length; i++) {
|
|
29654
29687
|
const token = tokens[i]?.toLowerCase();
|
|
@@ -29656,35 +29689,43 @@ function hasDestructiveDelete(command, projectRoot) {
|
|
|
29656
29689
|
if (token === "rm") {
|
|
29657
29690
|
const args = tokens.slice(i + 1);
|
|
29658
29691
|
const recursiveOrForce = args.some(
|
|
29659
|
-
(arg) => /^-[^-]*[rf]/i.test(arg) || arg === "--recursive" || arg === "--force"
|
|
29692
|
+
(arg) => /^-[^-]*[rf]/i.test(arg) || arg === "--recursive" || arg === "--force" || arg === "--no-preserve-root"
|
|
29660
29693
|
);
|
|
29661
|
-
if (recursiveOrForce
|
|
29694
|
+
if (!recursiveOrForce) continue;
|
|
29695
|
+
const targets = args.filter((arg) => !arg.startsWith("-") && !SHELL_OPERATORS.has(arg));
|
|
29696
|
+
if (targets.length === 0) return true;
|
|
29697
|
+
if (targets.some(isCatastrophicDeleteTarget)) return true;
|
|
29698
|
+
}
|
|
29699
|
+
if (token === "remove-item" || token === "ri") {
|
|
29700
|
+
const args = tokens.slice(i + 1);
|
|
29701
|
+
const recursive = args.some((arg) => {
|
|
29702
|
+
const a = arg.toLowerCase();
|
|
29703
|
+
return a === "-recurse" || a === "-force";
|
|
29704
|
+
});
|
|
29705
|
+
if (!recursive) continue;
|
|
29706
|
+
const targets = args.filter((arg) => !arg.startsWith("-") && !SHELL_OPERATORS.has(arg));
|
|
29707
|
+
if (targets.some(isCatastrophicDeleteTarget)) return true;
|
|
29662
29708
|
}
|
|
29663
29709
|
if (token === "rmdir" || token === "rd") {
|
|
29664
29710
|
const args = tokens.slice(i + 1);
|
|
29665
29711
|
const recursive = args.some((arg) => arg.toLowerCase() === "/s");
|
|
29666
|
-
if (recursive
|
|
29712
|
+
if (!recursive) continue;
|
|
29713
|
+
const targets = args.filter((arg) => !arg.startsWith("-") && !arg.startsWith("/") && !SHELL_OPERATORS.has(arg));
|
|
29714
|
+
if (targets.some(isCatastrophicDeleteTarget)) return true;
|
|
29667
29715
|
}
|
|
29668
29716
|
if (token === "del" || token === "erase") {
|
|
29669
|
-
|
|
29670
|
-
|
|
29671
|
-
|
|
29672
|
-
const args = tokens.slice(i + 1).map((arg) => arg.toLowerCase());
|
|
29673
|
-
const recursiveOrForce = args.includes("-recurse") || args.includes("-force");
|
|
29674
|
-
if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
|
|
29717
|
+
const args = tokens.slice(i + 1);
|
|
29718
|
+
const targets = args.filter((arg) => !arg.startsWith("-") && !arg.startsWith("/") && !SHELL_OPERATORS.has(arg));
|
|
29719
|
+
if (targets.some(isCatastrophicDeleteTarget)) return true;
|
|
29675
29720
|
}
|
|
29676
29721
|
}
|
|
29677
29722
|
return false;
|
|
29678
29723
|
}
|
|
29679
|
-
function isClearlyDestructiveBashCommand(command,
|
|
29724
|
+
function isClearlyDestructiveBashCommand(command, _projectRoot) {
|
|
29680
29725
|
const trimmed = command.trim();
|
|
29681
29726
|
if (!trimmed) return false;
|
|
29682
|
-
if (
|
|
29683
|
-
if (
|
|
29684
|
-
if (/\bcd\s+(?:\.\.|~|\/|[A-Za-z]:[\\/])/i.test(trimmed)) return true;
|
|
29685
|
-
if (PROJECT_ESCAPE_PATTERN.test(trimmed)) return true;
|
|
29686
|
-
const absolute = trimmed.match(ABSOLUTE_PATH_PATTERN)?.[0]?.trim().replace(/^['"]|['"]$/g, "");
|
|
29687
|
-
if (absolute && !pathLooksInsideProject(absolute, projectRoot)) return true;
|
|
29727
|
+
if (hasCatastrophicDelete(trimmed)) return true;
|
|
29728
|
+
if (CATASTROPHIC_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
|
|
29688
29729
|
return false;
|
|
29689
29730
|
}
|
|
29690
29731
|
|