@wrongstack/core 0.277.0 → 0.277.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.
@@ -24747,19 +24747,51 @@ var LruCache = class {
24747
24747
  // src/security/permission-policy.ts
24748
24748
  init_safe_json();
24749
24749
  init_tool_subject();
24750
- var DESTRUCTIVE_BASH_PATTERNS = [
24751
- /\bgit\s+(?:clean\s+-[^\s]*[xdf]|reset\s+--hard)\b/i,
24752
- /\b(?:drop|truncate)\s+(?:table|database|schema)\b/i,
24753
- /\bdelete\s+from\b/i,
24754
- /\b(?:mkfs|format|diskpart|shutdown|reboot)\b/i,
24755
- /\bchmod\s+-R\s+777\b/i,
24756
- /\bchown\s+-R\b/i,
24757
- /\b(?:curl|wget)\b.*\|\s*(?:sh|bash|zsh|pwsh|powershell)\b/i,
24758
- /\b(?:powershell|pwsh)\b.*(?:-encodedcommand|-enc)\b/i,
24759
- /:\(\)\s*\{\s*:\|:&\s*}\s*;/
24750
+ var CATASTROPHIC_PATTERNS = [
24751
+ /\b(?:mkfs(?:\.[a-z0-9]+)?|mke2fs|newfs)\b/i,
24752
+ // make a filesystem — wipes a partition
24753
+ /\bformat\s+[A-Za-z]:/i,
24754
+ // format C: — wipes a Windows volume
24755
+ /\bdiskpart\b/i,
24756
+ // Windows partition editor
24757
+ /\bdd\b[^|]*\bof=(?:\/dev\/|\\\\[.?]\\)/i,
24758
+ // dd writing straight to a raw device
24759
+ />\s*\/dev\/(?:sd|hd|nvme|disk|mapper|vd)/i,
24760
+ // redirect into a raw block device
24761
+ /:\(\)\s*\{\s*:\|:&\s*\}\s*;/
24762
+ // classic fork bomb
24760
24763
  ];
24761
- var PROJECT_ESCAPE_PATTERN = /(?:^|[\s"'])\.\.(?:[\\/]|$)/;
24762
- var ABSOLUTE_PATH_PATTERN = /(?:^|[\s"'])(?:~[\\/]|\/[A-Za-z0-9_.-]|[A-Za-z]:[\\/])/;
24764
+ var CATASTROPHIC_POSIX_ROOTS = /* @__PURE__ */ new Set([
24765
+ "/etc",
24766
+ "/usr",
24767
+ "/bin",
24768
+ "/sbin",
24769
+ "/lib",
24770
+ "/lib64",
24771
+ "/var",
24772
+ "/boot",
24773
+ "/dev",
24774
+ "/sys",
24775
+ "/proc",
24776
+ "/opt",
24777
+ "/root",
24778
+ "/home",
24779
+ "/srv",
24780
+ "/run",
24781
+ "/system",
24782
+ "/library",
24783
+ "/applications",
24784
+ "/users"
24785
+ ]);
24786
+ var CATASTROPHIC_WIN_SUBDIRS = /* @__PURE__ */ new Set([
24787
+ "windows",
24788
+ "system32",
24789
+ "winnt",
24790
+ "program files",
24791
+ "program files (x86)",
24792
+ "programdata",
24793
+ "users"
24794
+ ]);
24763
24795
  var SHELL_OPERATORS = /* @__PURE__ */ new Set(["&&", "||", "|", ";", ">", ">>", "<", "2>", "2>>"]);
24764
24796
  function getInputString(input, key) {
24765
24797
  if (!input || typeof input !== "object") return void 0;
@@ -24776,20 +24808,21 @@ function pathLooksInsideProject(rawPath, projectRoot) {
24776
24808
  function tokenizeShell(command) {
24777
24809
  return command.match(/"[^"]*"|'[^']*'|\S+/g)?.map((token) => token.replace(/^['"]|['"]$/g, "")) ?? [];
24778
24810
  }
24779
- function pathTokenIsOutsideProject(token, projectRoot) {
24780
- if (!token || SHELL_OPERATORS.has(token) || token.startsWith("-")) return false;
24781
- if (token === "/" || token === "~" || token === "." || token === "..") return token !== ".";
24782
- if (token.includes("*")) return true;
24783
- if (token.startsWith("..") || token.includes("../") || token.includes("..\\")) return true;
24784
- if (path4.isAbsolute(token) || token.startsWith("~/")) return !pathLooksInsideProject(token, projectRoot);
24811
+ function isCatastrophicDeleteTarget(rawTarget) {
24812
+ const t = rawTarget.replace(/^['"]|['"]$/g, "").trim();
24813
+ if (!t) return false;
24814
+ if (t === "*" || t === "." || t === "./" || t === ".\\" || t === "./*" || t === ".\\*") return true;
24815
+ const s = t.replace(/[\\/]\*+$/, "").replace(/[\\/]+$/, "");
24816
+ if (s === "") return true;
24817
+ if (s === "~" || /^\$HOME$/i.test(s) || /^%USERPROFILE%$/i.test(s)) return true;
24818
+ if (/^[A-Za-z]:$/.test(s)) return true;
24819
+ const norm = s.toLowerCase().replace(/\\/g, "/");
24820
+ if (CATASTROPHIC_POSIX_ROOTS.has(norm)) return true;
24821
+ const win = norm.match(/^[a-z]:\/([^/]+)$/);
24822
+ if (win?.[1] && CATASTROPHIC_WIN_SUBDIRS.has(win[1])) return true;
24785
24823
  return false;
24786
24824
  }
24787
- function hasDangerousDeleteTarget(tokens, start, projectRoot) {
24788
- const targets = tokens.slice(start).filter((token) => !token.startsWith("-") && !SHELL_OPERATORS.has(token));
24789
- if (targets.length === 0) return true;
24790
- return targets.some((target) => pathTokenIsOutsideProject(target, projectRoot));
24791
- }
24792
- function hasDestructiveDelete(command, projectRoot) {
24825
+ function hasCatastrophicDelete(command) {
24793
24826
  const tokens = tokenizeShell(command);
24794
24827
  for (let i = 0; i < tokens.length; i++) {
24795
24828
  const token = tokens[i]?.toLowerCase();
@@ -24797,35 +24830,43 @@ function hasDestructiveDelete(command, projectRoot) {
24797
24830
  if (token === "rm") {
24798
24831
  const args = tokens.slice(i + 1);
24799
24832
  const recursiveOrForce = args.some(
24800
- (arg) => /^-[^-]*[rf]/i.test(arg) || arg === "--recursive" || arg === "--force"
24833
+ (arg) => /^-[^-]*[rf]/i.test(arg) || arg === "--recursive" || arg === "--force" || arg === "--no-preserve-root"
24801
24834
  );
24802
- if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
24835
+ if (!recursiveOrForce) continue;
24836
+ const targets = args.filter((arg) => !arg.startsWith("-") && !SHELL_OPERATORS.has(arg));
24837
+ if (targets.length === 0) return true;
24838
+ if (targets.some(isCatastrophicDeleteTarget)) return true;
24839
+ }
24840
+ if (token === "remove-item" || token === "ri") {
24841
+ const args = tokens.slice(i + 1);
24842
+ const recursive = args.some((arg) => {
24843
+ const a = arg.toLowerCase();
24844
+ return a === "-recurse" || a === "-force";
24845
+ });
24846
+ if (!recursive) continue;
24847
+ const targets = args.filter((arg) => !arg.startsWith("-") && !SHELL_OPERATORS.has(arg));
24848
+ if (targets.some(isCatastrophicDeleteTarget)) return true;
24803
24849
  }
24804
24850
  if (token === "rmdir" || token === "rd") {
24805
24851
  const args = tokens.slice(i + 1);
24806
24852
  const recursive = args.some((arg) => arg.toLowerCase() === "/s");
24807
- if (recursive && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
24853
+ if (!recursive) continue;
24854
+ const targets = args.filter((arg) => !arg.startsWith("-") && !arg.startsWith("/") && !SHELL_OPERATORS.has(arg));
24855
+ if (targets.some(isCatastrophicDeleteTarget)) return true;
24808
24856
  }
24809
24857
  if (token === "del" || token === "erase") {
24810
- if (hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
24811
- }
24812
- if (token === "remove-item") {
24813
- const args = tokens.slice(i + 1).map((arg) => arg.toLowerCase());
24814
- const recursiveOrForce = args.includes("-recurse") || args.includes("-force");
24815
- if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
24858
+ const args = tokens.slice(i + 1);
24859
+ const targets = args.filter((arg) => !arg.startsWith("-") && !arg.startsWith("/") && !SHELL_OPERATORS.has(arg));
24860
+ if (targets.some(isCatastrophicDeleteTarget)) return true;
24816
24861
  }
24817
24862
  }
24818
24863
  return false;
24819
24864
  }
24820
- function isClearlyDestructiveBashCommand(command, projectRoot) {
24865
+ function isClearlyDestructiveBashCommand(command, _projectRoot) {
24821
24866
  const trimmed = command.trim();
24822
24867
  if (!trimmed) return false;
24823
- if (hasDestructiveDelete(trimmed, projectRoot)) return true;
24824
- if (DESTRUCTIVE_BASH_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
24825
- if (/\bcd\s+(?:\.\.|~|\/|[A-Za-z]:[\\/])/i.test(trimmed)) return true;
24826
- if (PROJECT_ESCAPE_PATTERN.test(trimmed)) return true;
24827
- const absolute = trimmed.match(ABSOLUTE_PATH_PATTERN)?.[0]?.trim().replace(/^['"]|['"]$/g, "");
24828
- if (absolute && !pathLooksInsideProject(absolute, projectRoot)) return true;
24868
+ if (hasCatastrophicDelete(trimmed)) return true;
24869
+ if (CATASTROPHIC_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
24829
24870
  return false;
24830
24871
  }
24831
24872