just-bash 2.9.3 → 2.9.4

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,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{A as c,B as d,C as e,I as f,J as g,K as h,L as i,M as j,N as k,O as l,y as a,z as b}from"./chunk-2ODUA7YH.js";import"./chunk-K5IXNHO5.js";import"./chunk-SE4C7FJY.js";import"./chunk-OBH7XN5N.js";import"./chunk-KGOUQS5A.js";export{d as escapeGlobChars,e as escapeRegexChars,l as expandRedirectTarget,g as expandWord,i as expandWordForPattern,h as expandWordForRegex,j as expandWordWithGlob,a as getArrayElements,c as getVariable,k as hasQuotedMultiValueAt,b as isArray,f as isWordFullyQuoted};
2
+ import{A as c,B as d,C as e,I as f,J as g,K as h,L as i,M as j,N as k,O as l,y as a,z as b}from"./chunk-B3E7BBYK.js";import"./chunk-K5IXNHO5.js";import"./chunk-SE4C7FJY.js";import"./chunk-OBH7XN5N.js";import"./chunk-KGOUQS5A.js";export{d as escapeGlobChars,e as escapeRegexChars,l as expandRedirectTarget,g as expandWord,i as expandWordForPattern,h as expandWordForRegex,j as expandWordWithGlob,a as getArrayElements,c as getVariable,k as hasQuotedMultiValueAt,b as isArray,f as isWordFullyQuoted};
@@ -1,3 +1,10 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
1
8
  // src/commands/python3/worker.ts
2
9
  import { parentPort, workerData } from "node:worker_threads";
3
10
  import { loadPyodide } from "pyodide";
@@ -75,6 +82,9 @@ function getBlockedGlobals() {
75
82
  strategy: "throw",
76
83
  reason: "process.dlopen allows loading native addons"
77
84
  },
85
+ // Note: process.mainModule is handled specially in defense-in-depth-box.ts
86
+ // and worker-defense-in-depth.ts because it may be undefined in ESM contexts
87
+ // but we still want to block both reading and setting it.
78
88
  // We also don't block `require` because:
79
89
  // 1. It may not exist in all environments (ESM)
80
90
  // 2. import() is the modern escape vector and can't be blocked this way
@@ -115,6 +125,21 @@ function getBlockedGlobals() {
115
125
  violationType: "webassembly",
116
126
  strategy: "throw",
117
127
  reason: "WebAssembly allows executing arbitrary compiled code"
128
+ },
129
+ // SharedArrayBuffer and Atomics can enable side-channel attacks
130
+ {
131
+ prop: "SharedArrayBuffer",
132
+ target: globalThis,
133
+ violationType: "shared_array_buffer",
134
+ strategy: "throw",
135
+ reason: "SharedArrayBuffer could enable side-channel communication or timing attacks"
136
+ },
137
+ {
138
+ prop: "Atomics",
139
+ target: globalThis,
140
+ violationType: "atomics",
141
+ strategy: "throw",
142
+ reason: "Atomics could enable side-channel communication or timing attacks"
118
143
  }
119
144
  // Note: Error.prepareStackTrace is handled specially in defense-in-depth-box.ts
120
145
  // because we only want to block SETTING it, not reading (V8 reads it internally)
@@ -491,6 +516,12 @@ var WorkerDefenseInDepth = class {
491
516
  if (!excludeTypes.has("error_prepare_stack_trace")) {
492
517
  this.protectErrorPrepareStackTrace();
493
518
  }
519
+ if (!excludeTypes.has("module_load")) {
520
+ this.protectModuleLoad();
521
+ }
522
+ if (!excludeTypes.has("process_main_module")) {
523
+ this.protectProcessMainModule();
524
+ }
494
525
  }
495
526
  /**
496
527
  * Protect against .constructor.constructor escape vector.
@@ -665,6 +696,123 @@ var WorkerDefenseInDepth = class {
665
696
  } catch {
666
697
  }
667
698
  }
699
+ /**
700
+ * Protect process.mainModule from being accessed or set.
701
+ *
702
+ * The attack vector is:
703
+ * ```
704
+ * process.mainModule.require('child_process').execSync('whoami')
705
+ * process.mainModule.constructor._load('vm')
706
+ * ```
707
+ *
708
+ * process.mainModule may be undefined in ESM contexts but could exist in
709
+ * CommonJS workers. We block both reading and setting.
710
+ */
711
+ protectProcessMainModule() {
712
+ if (typeof process === "undefined") return;
713
+ const self = this;
714
+ const auditMode = this.config.auditMode;
715
+ try {
716
+ const originalDescriptor = Object.getOwnPropertyDescriptor(
717
+ process,
718
+ "mainModule"
719
+ );
720
+ this.originalDescriptors.push({
721
+ target: process,
722
+ prop: "mainModule",
723
+ descriptor: originalDescriptor
724
+ });
725
+ const currentValue = originalDescriptor?.value;
726
+ if (currentValue !== void 0) {
727
+ Object.defineProperty(process, "mainModule", {
728
+ get() {
729
+ const message = "process.mainModule access is blocked in worker context";
730
+ const violation = self.recordViolation(
731
+ "process_main_module",
732
+ "process.mainModule",
733
+ message
734
+ );
735
+ if (!auditMode) {
736
+ throw new WorkerSecurityViolationError(message, violation);
737
+ }
738
+ return currentValue;
739
+ },
740
+ set(value) {
741
+ const message = "process.mainModule modification is blocked in worker context";
742
+ const violation = self.recordViolation(
743
+ "process_main_module",
744
+ "process.mainModule",
745
+ message
746
+ );
747
+ if (!auditMode) {
748
+ throw new WorkerSecurityViolationError(message, violation);
749
+ }
750
+ Object.defineProperty(process, "mainModule", {
751
+ value,
752
+ writable: true,
753
+ configurable: true
754
+ });
755
+ },
756
+ configurable: true
757
+ });
758
+ }
759
+ } catch {
760
+ }
761
+ }
762
+ /**
763
+ * Protect Module._load from being called.
764
+ *
765
+ * The attack vector is:
766
+ * ```
767
+ * module.constructor._load('child_process')
768
+ * require.main.constructor._load('vm')
769
+ * ```
770
+ *
771
+ * We access the Module class and replace _load with a blocking proxy.
772
+ */
773
+ protectModuleLoad() {
774
+ const self = this;
775
+ const auditMode = this.config.auditMode;
776
+ try {
777
+ let ModuleClass = null;
778
+ if (typeof process !== "undefined") {
779
+ const mainModule = process.mainModule;
780
+ if (mainModule && typeof mainModule === "object") {
781
+ ModuleClass = mainModule.constructor;
782
+ }
783
+ }
784
+ if (!ModuleClass && typeof __require !== "undefined" && typeof __require.main !== "undefined") {
785
+ ModuleClass = __require.main.constructor;
786
+ }
787
+ if (!ModuleClass || typeof ModuleClass._load !== "function") {
788
+ return;
789
+ }
790
+ const original = ModuleClass._load;
791
+ const descriptor = Object.getOwnPropertyDescriptor(ModuleClass, "_load");
792
+ this.originalDescriptors.push({
793
+ target: ModuleClass,
794
+ prop: "_load",
795
+ descriptor
796
+ });
797
+ const path = "Module._load";
798
+ const proxy = new this.originalProxy(original, {
799
+ apply(_target, _thisArg, _args) {
800
+ const message = `${path} is blocked in worker context`;
801
+ const violation = self.recordViolation("module_load", path, message);
802
+ if (!auditMode) {
803
+ throw new WorkerSecurityViolationError(message, violation);
804
+ }
805
+ return Reflect.apply(_target, _thisArg, _args);
806
+ }
807
+ });
808
+ Object.defineProperty(ModuleClass, "_load", {
809
+ value: proxy,
810
+ writable: true,
811
+ configurable: true
812
+ });
813
+ } catch {
814
+ }
815
+ }
668
816
  /**
669
817
  * Apply a single patch to a blocked global.
670
818
  */
@@ -2062,7 +2210,15 @@ var defense = null;
2062
2210
  async function initializeWithDefense() {
2063
2211
  await getPyodide();
2064
2212
  defense = new WorkerDefenseInDepth({
2065
- excludeViolationTypes: ["proxy", "setImmediate"],
2213
+ excludeViolationTypes: [
2214
+ "proxy",
2215
+ "setImmediate",
2216
+ // 3. SharedArrayBuffer/Atomics: Used by sync-fs-backend.ts for synchronous
2217
+ // filesystem communication between Pyodide's WASM thread and the main thread.
2218
+ // Without this, Pyodide cannot perform synchronous file I/O operations.
2219
+ "shared_array_buffer",
2220
+ "atomics"
2221
+ ],
2066
2222
  onViolation: (v) => {
2067
2223
  parentPort?.postMessage({ type: "security-violation", violation: v });
2068
2224
  }