@agenshield/interceptor
Advanced tools
| /** | ||
| * Debug Logger | ||
| * | ||
| * Writes diagnostic logs to /var/log/agenshield/interceptor.log using | ||
| * a captured (pre-patch) appendFileSync. Safe from interception. | ||
| */ | ||
| export declare function debugLog(msg: string): void; | ||
| //# sourceMappingURL=debug-log.d.ts.map |
| {"version":3,"file":"debug-log.d.ts","sourceRoot":"","sources":["../src/debug-log.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAM1C"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"sync-client.d.ts","sourceRoot":"","sources":["../../src/client/sync-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgBH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,iBAAiB;IAOtC;;OAEG;IACH,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC;IAU9D;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgFzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqCvB;;OAEG;IACH,IAAI,IAAI,OAAO;CAQhB"} | ||
| {"version":3,"file":"sync-client.d.ts","sourceRoot":"","sources":["../../src/client/sync-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,iBAAiB;IAOtC;;OAEG;IACH,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC;IAgB9D;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAsFzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAwCvB;;OAEG;IACH,IAAI,IAAI,OAAO;CAQhB"} |
+140
-18
@@ -105,2 +105,14 @@ "use strict"; | ||
| // libs/shield-interceptor/src/debug-log.ts | ||
| var fs = __toESM(require("node:fs"), 1); | ||
| var _appendFileSync = fs.appendFileSync.bind(fs); | ||
| var LOG_PATH = "/var/log/agenshield/interceptor.log"; | ||
| function debugLog(msg) { | ||
| try { | ||
| _appendFileSync(LOG_PATH, `[${(/* @__PURE__ */ new Date()).toISOString()}] [pid:${process.pid}] ${msg} | ||
| `); | ||
| } catch { | ||
| } | ||
| } | ||
| // libs/shield-interceptor/src/interceptors/base.ts | ||
@@ -131,3 +143,5 @@ var BaseInterceptor = class { | ||
| const port = parsed.port; | ||
| return port === String(this.brokerHttpPort) || port === "5200"; | ||
| const result = port === String(this.brokerHttpPort) || port === "5200"; | ||
| debugLog(`isBrokerUrl url=${url} hostname=${parsed.hostname} port=${port} brokerPort=${this.brokerHttpPort} result=${result}`); | ||
| return result; | ||
| } catch { | ||
@@ -148,5 +162,7 @@ return false; | ||
| const startTime = Date.now(); | ||
| debugLog(`base.checkPolicy START op=${operation} target=${target}`); | ||
| try { | ||
| this.eventReporter.intercept(operation, target); | ||
| const result = await this.policyEvaluator.check(operation, target); | ||
| debugLog(`base.checkPolicy evaluator result op=${operation} target=${target} allowed=${result.allowed} policyId=${result.policyId}`); | ||
| if (!result.allowed) { | ||
@@ -168,4 +184,6 @@ this.eventReporter.deny(operation, target, result.policyId, result.reason); | ||
| if (error instanceof PolicyDeniedError) { | ||
| debugLog(`base.checkPolicy DENIED op=${operation} target=${target} reason=${error.message}`); | ||
| throw error; | ||
| } | ||
| debugLog(`base.checkPolicy ERROR op=${operation} target=${target} error=${error.message} failOpen=${this.failOpen}`); | ||
| if (this.failOpen) { | ||
@@ -220,6 +238,10 @@ this.eventReporter.error( | ||
| } | ||
| if (this.isBrokerUrl(url)) { | ||
| const isBroker = this.isBrokerUrl(url); | ||
| debugLog(`fetch ENTER url=${url} isBroker=${isBroker}`); | ||
| if (isBroker) { | ||
| return this.originalFetch(input, init); | ||
| } | ||
| debugLog(`fetch checkPolicy START url=${url}`); | ||
| await this.checkPolicy("http_request", url); | ||
| debugLog(`fetch checkPolicy DONE url=${url}`); | ||
| try { | ||
@@ -264,2 +286,3 @@ const method = init?.method || "GET"; | ||
| } catch (error) { | ||
| debugLog(`fetch ERROR url=${url} error=${error.message}`); | ||
| if (error.name === "PolicyDeniedError") { | ||
@@ -269,2 +292,3 @@ throw error; | ||
| if (this.failOpen) { | ||
| debugLog(`fetch failOpen fallback url=${url}`); | ||
| return this.originalFetch(input, init); | ||
@@ -413,7 +437,7 @@ } | ||
| var import_node_child_process = require("node:child_process"); | ||
| var fs = __toESM(require("node:fs"), 1); | ||
| var fs2 = __toESM(require("node:fs"), 1); | ||
| var import_node_crypto = require("node:crypto"); | ||
| var _existsSync = fs.existsSync.bind(fs); | ||
| var _readFileSync = fs.readFileSync.bind(fs); | ||
| var _unlinkSync = fs.unlinkSync.bind(fs); | ||
| var _existsSync = fs2.existsSync.bind(fs2); | ||
| var _readFileSync = fs2.readFileSync.bind(fs2); | ||
| var _unlinkSync = fs2.unlinkSync.bind(fs2); | ||
| var _spawnSync = import_node_child_process.spawnSync; | ||
@@ -436,6 +460,12 @@ var _execSync = import_node_child_process.execSync; | ||
| request(method, params) { | ||
| debugLog(`syncClient.request START method=${method}`); | ||
| try { | ||
| return this.socketRequestSync(method, params); | ||
| } catch { | ||
| return this.httpRequestSync(method, params); | ||
| const result = this.socketRequestSync(method, params); | ||
| debugLog(`syncClient.request socket OK method=${method}`); | ||
| return result; | ||
| } catch (socketErr) { | ||
| debugLog(`syncClient.request socket FAILED: ${socketErr.message}, trying HTTP`); | ||
| const result = this.httpRequestSync(method, params); | ||
| debugLog(`syncClient.request http OK method=${method}`); | ||
| return result; | ||
| } | ||
@@ -486,3 +516,4 @@ } | ||
| try { | ||
| _spawnSync("/opt/agenshield/bin/node-bin", ["-e", script], { | ||
| debugLog(`syncClient.socketRequestSync _spawnSync START node-bin method=${method}`); | ||
| const spawnResult = _spawnSync("/opt/agenshield/bin/node-bin", ["-e", script], { | ||
| timeout: this.timeout + 1e3, | ||
@@ -492,4 +523,9 @@ stdio: "ignore", | ||
| }); | ||
| if (_existsSync(tmpFile)) { | ||
| const response = JSON.parse(_readFileSync(tmpFile, "utf-8")); | ||
| debugLog(`syncClient.socketRequestSync _spawnSync DONE status=${spawnResult?.status} signal=${spawnResult?.signal} error=${spawnResult?.error?.message || "none"}`); | ||
| const tmpExists = _existsSync(tmpFile); | ||
| debugLog(`syncClient.socketRequestSync tmpFile exists=${tmpExists}`); | ||
| if (tmpExists) { | ||
| const raw = _readFileSync(tmpFile, "utf-8"); | ||
| debugLog(`syncClient.socketRequestSync response raw=${raw.slice(0, 200)}`); | ||
| const response = JSON.parse(raw); | ||
| _unlinkSync(tmpFile); | ||
@@ -524,2 +560,3 @@ if (response.error) { | ||
| try { | ||
| debugLog(`syncClient.httpRequestSync curl START url=${url} method=${method}`); | ||
| const result = _execSync( | ||
@@ -532,2 +569,3 @@ `/usr/bin/curl -s -X POST -H "Content-Type: application/json" -d '${request.replace(/'/g, "\\'")}' "${url}"`, | ||
| ); | ||
| debugLog(`syncClient.httpRequestSync curl DONE len=${result?.length}`); | ||
| const response = JSON.parse(result); | ||
@@ -539,2 +577,3 @@ if (response.error) { | ||
| } catch (error) { | ||
| debugLog(`syncClient.httpRequestSync FAILED: ${error.message}`); | ||
| throw new Error(`Sync request failed: ${error.message}`); | ||
@@ -560,2 +599,3 @@ } | ||
| syncClient; | ||
| _checking = false; | ||
| originalExec = null; | ||
@@ -614,2 +654,7 @@ originalExecSync = null; | ||
| const callback = typeof args[args.length - 1] === "function" ? args.pop() : void 0; | ||
| debugLog(`cp.exec ENTER command=${command} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.exec SKIP (re-entrancy) command=${command}`); | ||
| return original(command, ...args, callback); | ||
| } | ||
| self.eventReporter.intercept("exec", command); | ||
@@ -630,4 +675,11 @@ self.checkPolicy("exec", command).then(() => { | ||
| const interceptedExecSync = function(command, options) { | ||
| self.eventReporter.intercept("exec", command); | ||
| debugLog(`cp.execSync ENTER command=${command} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.execSync SKIP (re-entrancy) command=${command}`); | ||
| return original(command, options); | ||
| } | ||
| self._checking = true; | ||
| try { | ||
| self.eventReporter.intercept("exec", command); | ||
| debugLog(`cp.execSync policy_check START command=${command}`); | ||
| const result = self.syncClient.request( | ||
@@ -637,2 +689,3 @@ "policy_check", | ||
| ); | ||
| debugLog(`cp.execSync policy_check DONE allowed=${result.allowed} command=${command}`); | ||
| if (!result.allowed) { | ||
@@ -645,2 +698,3 @@ throw new PolicyDeniedError(result.reason || "Operation denied by policy", { | ||
| } catch (error) { | ||
| debugLog(`cp.execSync policy_check ERROR: ${error.message} command=${command}`); | ||
| if (error instanceof PolicyDeniedError) { | ||
@@ -652,3 +706,6 @@ throw error; | ||
| } | ||
| } finally { | ||
| self._checking = false; | ||
| } | ||
| debugLog(`cp.execSync calling original command=${command}`); | ||
| return original(command, options); | ||
@@ -662,2 +719,8 @@ }; | ||
| const interceptedSpawn = function(command, args, options) { | ||
| const fullCmd = args ? `${command} ${args.join(" ")}` : command; | ||
| debugLog(`cp.spawn ENTER command=${fullCmd} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.spawn SKIP (re-entrancy) command=${fullCmd}`); | ||
| return original(command, args, options || {}); | ||
| } | ||
| const fullCommand = args ? `${command} ${args.join(" ")}` : command; | ||
@@ -677,4 +740,11 @@ self.eventReporter.intercept("exec", fullCommand); | ||
| const fullCommand = args ? `${command} ${args.join(" ")}` : command; | ||
| self.eventReporter.intercept("exec", fullCommand); | ||
| debugLog(`cp.spawnSync ENTER command=${fullCommand} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.spawnSync SKIP (re-entrancy) command=${fullCommand}`); | ||
| return original(command, args, options); | ||
| } | ||
| self._checking = true; | ||
| try { | ||
| self.eventReporter.intercept("exec", fullCommand); | ||
| debugLog(`cp.spawnSync policy_check START command=${fullCommand}`); | ||
| const result = self.syncClient.request( | ||
@@ -684,2 +754,3 @@ "policy_check", | ||
| ); | ||
| debugLog(`cp.spawnSync policy_check DONE allowed=${result.allowed} command=${fullCommand}`); | ||
| if (!result.allowed) { | ||
@@ -697,2 +768,3 @@ return { | ||
| } catch (error) { | ||
| debugLog(`cp.spawnSync policy_check ERROR: ${error.message} command=${fullCommand}`); | ||
| if (!self.failOpen) { | ||
@@ -709,3 +781,6 @@ return { | ||
| } | ||
| } finally { | ||
| self._checking = false; | ||
| } | ||
| debugLog(`cp.spawnSync calling original command=${fullCommand}`); | ||
| return original(command, args, options); | ||
@@ -718,2 +793,5 @@ }; | ||
| return function interceptedExecFile(file, ...args) { | ||
| if (self._checking) { | ||
| return original(file, ...args); | ||
| } | ||
| self.eventReporter.intercept("exec", file); | ||
@@ -730,2 +808,5 @@ self.checkPolicy("exec", file).catch((error) => { | ||
| const interceptedFork = function(modulePath, args, options) { | ||
| if (self._checking) { | ||
| return original(modulePath, args, options); | ||
| } | ||
| const pathStr = modulePath.toString(); | ||
@@ -743,2 +824,3 @@ self.eventReporter.intercept("exec", `fork:${pathStr}`); | ||
| // libs/shield-interceptor/src/interceptors/fs.ts | ||
| var import_node_url = require("node:url"); | ||
| var fsModule = require("node:fs"); | ||
@@ -758,5 +840,19 @@ var fsPromisesModule = require("node:fs/promises"); | ||
| } | ||
| function normalizePathArg(p) { | ||
| if (p instanceof URL) { | ||
| return (0, import_node_url.fileURLToPath)(p); | ||
| } | ||
| const s = p.toString(); | ||
| if (s.startsWith("file://")) { | ||
| try { | ||
| return (0, import_node_url.fileURLToPath)(new URL(s)); | ||
| } catch { | ||
| } | ||
| } | ||
| return s; | ||
| } | ||
| var FsInterceptor = class extends BaseInterceptor { | ||
| syncClient; | ||
| originals = /* @__PURE__ */ new Map(); | ||
| _checking = false; | ||
| constructor(options) { | ||
@@ -817,8 +913,16 @@ super(options); | ||
| safeOverride(module2, methodName, function intercepted(path, ...args) { | ||
| const pathString = path.toString(); | ||
| const pathString = normalizePathArg(path); | ||
| const callback = typeof args[args.length - 1] === "function" ? args.pop() : void 0; | ||
| debugLog(`fs.${methodName} ENTER (async) path=${pathString} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`fs.${methodName} SKIP (re-entrancy, async) path=${pathString}`); | ||
| original.call(module2, path, ...args, callback); | ||
| return; | ||
| } | ||
| self.eventReporter.intercept(operation, pathString); | ||
| self.checkPolicy(operation, pathString).then(() => { | ||
| debugLog(`fs.${methodName} policy OK (async) path=${pathString}`); | ||
| original.call(module2, path, ...args, callback); | ||
| }).catch((error) => { | ||
| debugLog(`fs.${methodName} policy ERROR (async): ${error.message} path=${pathString}`); | ||
| if (callback) { | ||
@@ -837,5 +941,12 @@ callback(error); | ||
| safeOverride(module2, methodName, function interceptedSync(path, ...args) { | ||
| const pathString = path.toString(); | ||
| self.eventReporter.intercept(operation, pathString); | ||
| const pathString = normalizePathArg(path); | ||
| debugLog(`fs.${methodName} ENTER path=${pathString} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`fs.${methodName} SKIP (re-entrancy) path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
| } | ||
| self._checking = true; | ||
| try { | ||
| self.eventReporter.intercept(operation, pathString); | ||
| debugLog(`fs.${methodName} policy_check START path=${pathString}`); | ||
| const result = self.syncClient.request( | ||
@@ -845,2 +956,3 @@ "policy_check", | ||
| ); | ||
| debugLog(`fs.${methodName} policy_check DONE allowed=${result.allowed} path=${pathString}`); | ||
| if (!result.allowed) { | ||
@@ -853,2 +965,3 @@ throw new PolicyDeniedError(result.reason || "Operation denied by policy", { | ||
| } catch (error) { | ||
| debugLog(`fs.${methodName} policy_check ERROR: ${error.message} path=${pathString}`); | ||
| if (error instanceof PolicyDeniedError) { | ||
@@ -860,3 +973,6 @@ throw error; | ||
| } | ||
| } finally { | ||
| self._checking = false; | ||
| } | ||
| debugLog(`fs.${methodName} calling original path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
@@ -872,5 +988,11 @@ }); | ||
| safeOverride(module2, methodName, async function interceptedPromise(path, ...args) { | ||
| const pathString = path.toString(); | ||
| const pathString = normalizePathArg(path); | ||
| debugLog(`fsPromises.${methodName} ENTER path=${pathString} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`fsPromises.${methodName} SKIP (re-entrancy) path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
| } | ||
| self.eventReporter.intercept(operation, pathString); | ||
| await self.checkPolicy(operation, pathString); | ||
| debugLog(`fsPromises.${methodName} policy OK path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
@@ -877,0 +999,0 @@ }); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/interceptors/base.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,WAAW,CAAC;IACpB,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,8BAAsB,eAAe;IACnC,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC;IAC9B,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAC3C,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;IACvC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,SAAS,EAAE,OAAO,CAAS;IACrC,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,EAAE,sBAAsB;IAQ3C;;OAEG;IACH,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAa3C;;OAEG;IACH,QAAQ,CAAC,OAAO,IAAI,IAAI;IAExB;;OAEG;IACH,QAAQ,CAAC,SAAS,IAAI,IAAI;IAE1B;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;cACa,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IA0ChB;;OAEG;IACH,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAGvC"} | ||
| {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/interceptors/base.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAI3D,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,WAAW,CAAC;IACpB,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,8BAAsB,eAAe;IACnC,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC;IAC9B,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAC3C,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;IACvC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,SAAS,EAAE,OAAO,CAAS;IACrC,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,EAAE,sBAAsB;IAQ3C;;OAEG;IACH,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAe3C;;OAEG;IACH,QAAQ,CAAC,OAAO,IAAI,IAAI;IAExB;;OAEG;IACH,QAAQ,CAAC,SAAS,IAAI,IAAI;IAE1B;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;cACa,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IA8ChB;;OAEG;IACH,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAGvC"} |
@@ -9,2 +9,3 @@ /** | ||
| private syncClient; | ||
| private _checking; | ||
| private originalExec; | ||
@@ -11,0 +12,0 @@ private originalExecSync; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"child-process.d.ts","sourceRoot":"","sources":["../../src/interceptors/child-process.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAQzE,qBAAa,uBAAwB,SAAQ,eAAe;IAC1D,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAyC;IAC7D,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,iBAAiB,CAA8C;IACvE,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,YAAY,CAAyC;gBAEjD,OAAO,EAAE,sBAAsB;IAU3C,OAAO,IAAI,IAAI;IAsBf,SAAS,IAAI,IAAI;IAmBjB,OAAO,CAAC,qBAAqB;IAgC7B,OAAO,CAAC,yBAAyB;IAuCjC,OAAO,CAAC,sBAAsB;IAyB9B,OAAO,CAAC,0BAA0B;IAiDlC,OAAO,CAAC,yBAAyB;IAmBjC,OAAO,CAAC,qBAAqB;CAsB9B"} | ||
| {"version":3,"file":"child-process.d.ts","sourceRoot":"","sources":["../../src/interceptors/child-process.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAC;AASzE,qBAAa,uBAAwB,SAAQ,eAAe;IAC1D,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAyC;IAC7D,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,iBAAiB,CAA8C;IACvE,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,YAAY,CAAyC;gBAEjD,OAAO,EAAE,sBAAsB;IAU3C,OAAO,IAAI,IAAI;IAsBf,SAAS,IAAI,IAAI;IAmBjB,OAAO,CAAC,qBAAqB;IAwC7B,OAAO,CAAC,yBAAyB;IAsDjC,OAAO,CAAC,sBAAsB;IAkC9B,OAAO,CAAC,0BAA0B;IA+DlC,OAAO,CAAC,yBAAyB;IAwBjC,OAAO,CAAC,qBAAqB;CA2B9B"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/interceptors/fetch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAEzE,qBAAa,gBAAiB,SAAQ,eAAe;IACnD,OAAO,CAAC,aAAa,CAA6B;gBAEtC,OAAO,EAAE,sBAAsB;IAI3C,OAAO,IAAI,IAAI;IAYf,SAAS,IAAI,IAAI;YAQH,gBAAgB;CA0F/B"} | ||
| {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/interceptors/fetch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAGzE,qBAAa,gBAAiB,SAAQ,eAAe;IACnD,OAAO,CAAC,aAAa,CAA6B;gBAEtC,OAAO,EAAE,sBAAsB;IAI3C,OAAO,IAAI,IAAI;IAYf,SAAS,IAAI,IAAI;YAQH,gBAAgB;CAiG/B"} |
@@ -10,2 +10,3 @@ /** | ||
| private originals; | ||
| private _checking; | ||
| constructor(options: BaseInterceptorOptions); | ||
@@ -12,0 +13,0 @@ install(): void; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/interceptors/fs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAC;AA2BzE,qBAAa,aAAc,SAAQ,eAAe;IAChD,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAoC;gBAEzC,OAAO,EAAE,sBAAsB;IAU3C,OAAO,IAAI,IAAI;IAoCf,SAAS,IAAI,IAAI;IAcjB,OAAO,CAAC,eAAe;IAuCvB,OAAO,CAAC,mBAAmB;IAgD3B,OAAO,CAAC,sBAAsB;CA2B/B"} | ||
| {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/interceptors/fs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAC;AA4CzE,qBAAa,aAAc,SAAQ,eAAe;IAChD,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,sBAAsB;IAU3C,OAAO,IAAI,IAAI;IAoCf,SAAS,IAAI,IAAI;IAcjB,OAAO,CAAC,eAAe;IAkDvB,OAAO,CAAC,mBAAmB;IA+D3B,OAAO,CAAC,sBAAsB;CAoC/B"} |
+2
-2
| { | ||
| "name": "@agenshield/interceptor", | ||
| "version": "0.6.0", | ||
| "version": "0.6.1", | ||
| "type": "module", | ||
@@ -28,3 +28,3 @@ "description": "Node.js runtime interception via ESM loader and CJS preload", | ||
| "dependencies": { | ||
| "@agenshield/ipc": "0.6.0" | ||
| "@agenshield/ipc": "0.6.1" | ||
| }, | ||
@@ -31,0 +31,0 @@ "devDependencies": { |
+140
-18
@@ -80,2 +80,14 @@ "use strict"; | ||
| // libs/shield-interceptor/src/debug-log.ts | ||
| var fs = __toESM(require("node:fs"), 1); | ||
| var _appendFileSync = fs.appendFileSync.bind(fs); | ||
| var LOG_PATH = "/var/log/agenshield/interceptor.log"; | ||
| function debugLog(msg) { | ||
| try { | ||
| _appendFileSync(LOG_PATH, `[${(/* @__PURE__ */ new Date()).toISOString()}] [pid:${process.pid}] ${msg} | ||
| `); | ||
| } catch { | ||
| } | ||
| } | ||
| // libs/shield-interceptor/src/interceptors/base.ts | ||
@@ -106,3 +118,5 @@ var BaseInterceptor = class { | ||
| const port = parsed.port; | ||
| return port === String(this.brokerHttpPort) || port === "5200"; | ||
| const result = port === String(this.brokerHttpPort) || port === "5200"; | ||
| debugLog(`isBrokerUrl url=${url} hostname=${parsed.hostname} port=${port} brokerPort=${this.brokerHttpPort} result=${result}`); | ||
| return result; | ||
| } catch { | ||
@@ -123,5 +137,7 @@ return false; | ||
| const startTime = Date.now(); | ||
| debugLog(`base.checkPolicy START op=${operation} target=${target}`); | ||
| try { | ||
| this.eventReporter.intercept(operation, target); | ||
| const result = await this.policyEvaluator.check(operation, target); | ||
| debugLog(`base.checkPolicy evaluator result op=${operation} target=${target} allowed=${result.allowed} policyId=${result.policyId}`); | ||
| if (!result.allowed) { | ||
@@ -143,4 +159,6 @@ this.eventReporter.deny(operation, target, result.policyId, result.reason); | ||
| if (error instanceof PolicyDeniedError) { | ||
| debugLog(`base.checkPolicy DENIED op=${operation} target=${target} reason=${error.message}`); | ||
| throw error; | ||
| } | ||
| debugLog(`base.checkPolicy ERROR op=${operation} target=${target} error=${error.message} failOpen=${this.failOpen}`); | ||
| if (this.failOpen) { | ||
@@ -195,6 +213,10 @@ this.eventReporter.error( | ||
| } | ||
| if (this.isBrokerUrl(url)) { | ||
| const isBroker = this.isBrokerUrl(url); | ||
| debugLog(`fetch ENTER url=${url} isBroker=${isBroker}`); | ||
| if (isBroker) { | ||
| return this.originalFetch(input, init); | ||
| } | ||
| debugLog(`fetch checkPolicy START url=${url}`); | ||
| await this.checkPolicy("http_request", url); | ||
| debugLog(`fetch checkPolicy DONE url=${url}`); | ||
| try { | ||
@@ -239,2 +261,3 @@ const method = init?.method || "GET"; | ||
| } catch (error) { | ||
| debugLog(`fetch ERROR url=${url} error=${error.message}`); | ||
| if (error.name === "PolicyDeniedError") { | ||
@@ -244,2 +267,3 @@ throw error; | ||
| if (this.failOpen) { | ||
| debugLog(`fetch failOpen fallback url=${url}`); | ||
| return this.originalFetch(input, init); | ||
@@ -388,7 +412,7 @@ } | ||
| var import_node_child_process = require("node:child_process"); | ||
| var fs = __toESM(require("node:fs"), 1); | ||
| var fs2 = __toESM(require("node:fs"), 1); | ||
| var import_node_crypto = require("node:crypto"); | ||
| var _existsSync = fs.existsSync.bind(fs); | ||
| var _readFileSync = fs.readFileSync.bind(fs); | ||
| var _unlinkSync = fs.unlinkSync.bind(fs); | ||
| var _existsSync = fs2.existsSync.bind(fs2); | ||
| var _readFileSync = fs2.readFileSync.bind(fs2); | ||
| var _unlinkSync = fs2.unlinkSync.bind(fs2); | ||
| var _spawnSync = import_node_child_process.spawnSync; | ||
@@ -411,6 +435,12 @@ var _execSync = import_node_child_process.execSync; | ||
| request(method, params) { | ||
| debugLog(`syncClient.request START method=${method}`); | ||
| try { | ||
| return this.socketRequestSync(method, params); | ||
| } catch { | ||
| return this.httpRequestSync(method, params); | ||
| const result = this.socketRequestSync(method, params); | ||
| debugLog(`syncClient.request socket OK method=${method}`); | ||
| return result; | ||
| } catch (socketErr) { | ||
| debugLog(`syncClient.request socket FAILED: ${socketErr.message}, trying HTTP`); | ||
| const result = this.httpRequestSync(method, params); | ||
| debugLog(`syncClient.request http OK method=${method}`); | ||
| return result; | ||
| } | ||
@@ -461,3 +491,4 @@ } | ||
| try { | ||
| _spawnSync("/opt/agenshield/bin/node-bin", ["-e", script], { | ||
| debugLog(`syncClient.socketRequestSync _spawnSync START node-bin method=${method}`); | ||
| const spawnResult = _spawnSync("/opt/agenshield/bin/node-bin", ["-e", script], { | ||
| timeout: this.timeout + 1e3, | ||
@@ -467,4 +498,9 @@ stdio: "ignore", | ||
| }); | ||
| if (_existsSync(tmpFile)) { | ||
| const response = JSON.parse(_readFileSync(tmpFile, "utf-8")); | ||
| debugLog(`syncClient.socketRequestSync _spawnSync DONE status=${spawnResult?.status} signal=${spawnResult?.signal} error=${spawnResult?.error?.message || "none"}`); | ||
| const tmpExists = _existsSync(tmpFile); | ||
| debugLog(`syncClient.socketRequestSync tmpFile exists=${tmpExists}`); | ||
| if (tmpExists) { | ||
| const raw = _readFileSync(tmpFile, "utf-8"); | ||
| debugLog(`syncClient.socketRequestSync response raw=${raw.slice(0, 200)}`); | ||
| const response = JSON.parse(raw); | ||
| _unlinkSync(tmpFile); | ||
@@ -499,2 +535,3 @@ if (response.error) { | ||
| try { | ||
| debugLog(`syncClient.httpRequestSync curl START url=${url} method=${method}`); | ||
| const result = _execSync( | ||
@@ -507,2 +544,3 @@ `/usr/bin/curl -s -X POST -H "Content-Type: application/json" -d '${request.replace(/'/g, "\\'")}' "${url}"`, | ||
| ); | ||
| debugLog(`syncClient.httpRequestSync curl DONE len=${result?.length}`); | ||
| const response = JSON.parse(result); | ||
@@ -514,2 +552,3 @@ if (response.error) { | ||
| } catch (error) { | ||
| debugLog(`syncClient.httpRequestSync FAILED: ${error.message}`); | ||
| throw new Error(`Sync request failed: ${error.message}`); | ||
@@ -535,2 +574,3 @@ } | ||
| syncClient; | ||
| _checking = false; | ||
| originalExec = null; | ||
@@ -589,2 +629,7 @@ originalExecSync = null; | ||
| const callback = typeof args[args.length - 1] === "function" ? args.pop() : void 0; | ||
| debugLog(`cp.exec ENTER command=${command} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.exec SKIP (re-entrancy) command=${command}`); | ||
| return original(command, ...args, callback); | ||
| } | ||
| self.eventReporter.intercept("exec", command); | ||
@@ -605,4 +650,11 @@ self.checkPolicy("exec", command).then(() => { | ||
| const interceptedExecSync = function(command, options) { | ||
| self.eventReporter.intercept("exec", command); | ||
| debugLog(`cp.execSync ENTER command=${command} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.execSync SKIP (re-entrancy) command=${command}`); | ||
| return original(command, options); | ||
| } | ||
| self._checking = true; | ||
| try { | ||
| self.eventReporter.intercept("exec", command); | ||
| debugLog(`cp.execSync policy_check START command=${command}`); | ||
| const result = self.syncClient.request( | ||
@@ -612,2 +664,3 @@ "policy_check", | ||
| ); | ||
| debugLog(`cp.execSync policy_check DONE allowed=${result.allowed} command=${command}`); | ||
| if (!result.allowed) { | ||
@@ -620,2 +673,3 @@ throw new PolicyDeniedError(result.reason || "Operation denied by policy", { | ||
| } catch (error) { | ||
| debugLog(`cp.execSync policy_check ERROR: ${error.message} command=${command}`); | ||
| if (error instanceof PolicyDeniedError) { | ||
@@ -627,3 +681,6 @@ throw error; | ||
| } | ||
| } finally { | ||
| self._checking = false; | ||
| } | ||
| debugLog(`cp.execSync calling original command=${command}`); | ||
| return original(command, options); | ||
@@ -637,2 +694,8 @@ }; | ||
| const interceptedSpawn = function(command, args, options) { | ||
| const fullCmd = args ? `${command} ${args.join(" ")}` : command; | ||
| debugLog(`cp.spawn ENTER command=${fullCmd} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.spawn SKIP (re-entrancy) command=${fullCmd}`); | ||
| return original(command, args, options || {}); | ||
| } | ||
| const fullCommand = args ? `${command} ${args.join(" ")}` : command; | ||
@@ -652,4 +715,11 @@ self.eventReporter.intercept("exec", fullCommand); | ||
| const fullCommand = args ? `${command} ${args.join(" ")}` : command; | ||
| self.eventReporter.intercept("exec", fullCommand); | ||
| debugLog(`cp.spawnSync ENTER command=${fullCommand} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.spawnSync SKIP (re-entrancy) command=${fullCommand}`); | ||
| return original(command, args, options); | ||
| } | ||
| self._checking = true; | ||
| try { | ||
| self.eventReporter.intercept("exec", fullCommand); | ||
| debugLog(`cp.spawnSync policy_check START command=${fullCommand}`); | ||
| const result = self.syncClient.request( | ||
@@ -659,2 +729,3 @@ "policy_check", | ||
| ); | ||
| debugLog(`cp.spawnSync policy_check DONE allowed=${result.allowed} command=${fullCommand}`); | ||
| if (!result.allowed) { | ||
@@ -672,2 +743,3 @@ return { | ||
| } catch (error) { | ||
| debugLog(`cp.spawnSync policy_check ERROR: ${error.message} command=${fullCommand}`); | ||
| if (!self.failOpen) { | ||
@@ -684,3 +756,6 @@ return { | ||
| } | ||
| } finally { | ||
| self._checking = false; | ||
| } | ||
| debugLog(`cp.spawnSync calling original command=${fullCommand}`); | ||
| return original(command, args, options); | ||
@@ -693,2 +768,5 @@ }; | ||
| return function interceptedExecFile(file, ...args) { | ||
| if (self._checking) { | ||
| return original(file, ...args); | ||
| } | ||
| self.eventReporter.intercept("exec", file); | ||
@@ -705,2 +783,5 @@ self.checkPolicy("exec", file).catch((error) => { | ||
| const interceptedFork = function(modulePath, args, options) { | ||
| if (self._checking) { | ||
| return original(modulePath, args, options); | ||
| } | ||
| const pathStr = modulePath.toString(); | ||
@@ -718,2 +799,3 @@ self.eventReporter.intercept("exec", `fork:${pathStr}`); | ||
| // libs/shield-interceptor/src/interceptors/fs.ts | ||
| var import_node_url = require("node:url"); | ||
| var fsModule = require("node:fs"); | ||
@@ -733,5 +815,19 @@ var fsPromisesModule = require("node:fs/promises"); | ||
| } | ||
| function normalizePathArg(p) { | ||
| if (p instanceof URL) { | ||
| return (0, import_node_url.fileURLToPath)(p); | ||
| } | ||
| const s = p.toString(); | ||
| if (s.startsWith("file://")) { | ||
| try { | ||
| return (0, import_node_url.fileURLToPath)(new URL(s)); | ||
| } catch { | ||
| } | ||
| } | ||
| return s; | ||
| } | ||
| var FsInterceptor = class extends BaseInterceptor { | ||
| syncClient; | ||
| originals = /* @__PURE__ */ new Map(); | ||
| _checking = false; | ||
| constructor(options) { | ||
@@ -792,8 +888,16 @@ super(options); | ||
| safeOverride(module2, methodName, function intercepted(path, ...args) { | ||
| const pathString = path.toString(); | ||
| const pathString = normalizePathArg(path); | ||
| const callback = typeof args[args.length - 1] === "function" ? args.pop() : void 0; | ||
| debugLog(`fs.${methodName} ENTER (async) path=${pathString} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`fs.${methodName} SKIP (re-entrancy, async) path=${pathString}`); | ||
| original.call(module2, path, ...args, callback); | ||
| return; | ||
| } | ||
| self.eventReporter.intercept(operation, pathString); | ||
| self.checkPolicy(operation, pathString).then(() => { | ||
| debugLog(`fs.${methodName} policy OK (async) path=${pathString}`); | ||
| original.call(module2, path, ...args, callback); | ||
| }).catch((error) => { | ||
| debugLog(`fs.${methodName} policy ERROR (async): ${error.message} path=${pathString}`); | ||
| if (callback) { | ||
@@ -812,5 +916,12 @@ callback(error); | ||
| safeOverride(module2, methodName, function interceptedSync(path, ...args) { | ||
| const pathString = path.toString(); | ||
| self.eventReporter.intercept(operation, pathString); | ||
| const pathString = normalizePathArg(path); | ||
| debugLog(`fs.${methodName} ENTER path=${pathString} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`fs.${methodName} SKIP (re-entrancy) path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
| } | ||
| self._checking = true; | ||
| try { | ||
| self.eventReporter.intercept(operation, pathString); | ||
| debugLog(`fs.${methodName} policy_check START path=${pathString}`); | ||
| const result = self.syncClient.request( | ||
@@ -820,2 +931,3 @@ "policy_check", | ||
| ); | ||
| debugLog(`fs.${methodName} policy_check DONE allowed=${result.allowed} path=${pathString}`); | ||
| if (!result.allowed) { | ||
@@ -828,2 +940,3 @@ throw new PolicyDeniedError(result.reason || "Operation denied by policy", { | ||
| } catch (error) { | ||
| debugLog(`fs.${methodName} policy_check ERROR: ${error.message} path=${pathString}`); | ||
| if (error instanceof PolicyDeniedError) { | ||
@@ -835,3 +948,6 @@ throw error; | ||
| } | ||
| } finally { | ||
| self._checking = false; | ||
| } | ||
| debugLog(`fs.${methodName} calling original path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
@@ -847,5 +963,11 @@ }); | ||
| safeOverride(module2, methodName, async function interceptedPromise(path, ...args) { | ||
| const pathString = path.toString(); | ||
| const pathString = normalizePathArg(path); | ||
| debugLog(`fsPromises.${methodName} ENTER path=${pathString} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`fsPromises.${methodName} SKIP (re-entrancy) path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
| } | ||
| self.eventReporter.intercept(operation, pathString); | ||
| await self.checkPolicy(operation, pathString); | ||
| debugLog(`fsPromises.${methodName} policy OK path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
@@ -852,0 +974,0 @@ }); |
+140
-18
@@ -80,2 +80,14 @@ "use strict"; | ||
| // libs/shield-interceptor/src/debug-log.ts | ||
| var fs = __toESM(require("node:fs"), 1); | ||
| var _appendFileSync = fs.appendFileSync.bind(fs); | ||
| var LOG_PATH = "/var/log/agenshield/interceptor.log"; | ||
| function debugLog(msg) { | ||
| try { | ||
| _appendFileSync(LOG_PATH, `[${(/* @__PURE__ */ new Date()).toISOString()}] [pid:${process.pid}] ${msg} | ||
| `); | ||
| } catch { | ||
| } | ||
| } | ||
| // libs/shield-interceptor/src/interceptors/base.ts | ||
@@ -106,3 +118,5 @@ var BaseInterceptor = class { | ||
| const port = parsed.port; | ||
| return port === String(this.brokerHttpPort) || port === "5200"; | ||
| const result = port === String(this.brokerHttpPort) || port === "5200"; | ||
| debugLog(`isBrokerUrl url=${url} hostname=${parsed.hostname} port=${port} brokerPort=${this.brokerHttpPort} result=${result}`); | ||
| return result; | ||
| } catch { | ||
@@ -123,5 +137,7 @@ return false; | ||
| const startTime = Date.now(); | ||
| debugLog(`base.checkPolicy START op=${operation} target=${target}`); | ||
| try { | ||
| this.eventReporter.intercept(operation, target); | ||
| const result = await this.policyEvaluator.check(operation, target); | ||
| debugLog(`base.checkPolicy evaluator result op=${operation} target=${target} allowed=${result.allowed} policyId=${result.policyId}`); | ||
| if (!result.allowed) { | ||
@@ -143,4 +159,6 @@ this.eventReporter.deny(operation, target, result.policyId, result.reason); | ||
| if (error instanceof PolicyDeniedError) { | ||
| debugLog(`base.checkPolicy DENIED op=${operation} target=${target} reason=${error.message}`); | ||
| throw error; | ||
| } | ||
| debugLog(`base.checkPolicy ERROR op=${operation} target=${target} error=${error.message} failOpen=${this.failOpen}`); | ||
| if (this.failOpen) { | ||
@@ -195,6 +213,10 @@ this.eventReporter.error( | ||
| } | ||
| if (this.isBrokerUrl(url)) { | ||
| const isBroker = this.isBrokerUrl(url); | ||
| debugLog(`fetch ENTER url=${url} isBroker=${isBroker}`); | ||
| if (isBroker) { | ||
| return this.originalFetch(input, init); | ||
| } | ||
| debugLog(`fetch checkPolicy START url=${url}`); | ||
| await this.checkPolicy("http_request", url); | ||
| debugLog(`fetch checkPolicy DONE url=${url}`); | ||
| try { | ||
@@ -239,2 +261,3 @@ const method = init?.method || "GET"; | ||
| } catch (error) { | ||
| debugLog(`fetch ERROR url=${url} error=${error.message}`); | ||
| if (error.name === "PolicyDeniedError") { | ||
@@ -244,2 +267,3 @@ throw error; | ||
| if (this.failOpen) { | ||
| debugLog(`fetch failOpen fallback url=${url}`); | ||
| return this.originalFetch(input, init); | ||
@@ -388,7 +412,7 @@ } | ||
| var import_node_child_process = require("node:child_process"); | ||
| var fs = __toESM(require("node:fs"), 1); | ||
| var fs2 = __toESM(require("node:fs"), 1); | ||
| var import_node_crypto = require("node:crypto"); | ||
| var _existsSync = fs.existsSync.bind(fs); | ||
| var _readFileSync = fs.readFileSync.bind(fs); | ||
| var _unlinkSync = fs.unlinkSync.bind(fs); | ||
| var _existsSync = fs2.existsSync.bind(fs2); | ||
| var _readFileSync = fs2.readFileSync.bind(fs2); | ||
| var _unlinkSync = fs2.unlinkSync.bind(fs2); | ||
| var _spawnSync = import_node_child_process.spawnSync; | ||
@@ -411,6 +435,12 @@ var _execSync = import_node_child_process.execSync; | ||
| request(method, params) { | ||
| debugLog(`syncClient.request START method=${method}`); | ||
| try { | ||
| return this.socketRequestSync(method, params); | ||
| } catch { | ||
| return this.httpRequestSync(method, params); | ||
| const result = this.socketRequestSync(method, params); | ||
| debugLog(`syncClient.request socket OK method=${method}`); | ||
| return result; | ||
| } catch (socketErr) { | ||
| debugLog(`syncClient.request socket FAILED: ${socketErr.message}, trying HTTP`); | ||
| const result = this.httpRequestSync(method, params); | ||
| debugLog(`syncClient.request http OK method=${method}`); | ||
| return result; | ||
| } | ||
@@ -461,3 +491,4 @@ } | ||
| try { | ||
| _spawnSync("/opt/agenshield/bin/node-bin", ["-e", script], { | ||
| debugLog(`syncClient.socketRequestSync _spawnSync START node-bin method=${method}`); | ||
| const spawnResult = _spawnSync("/opt/agenshield/bin/node-bin", ["-e", script], { | ||
| timeout: this.timeout + 1e3, | ||
@@ -467,4 +498,9 @@ stdio: "ignore", | ||
| }); | ||
| if (_existsSync(tmpFile)) { | ||
| const response = JSON.parse(_readFileSync(tmpFile, "utf-8")); | ||
| debugLog(`syncClient.socketRequestSync _spawnSync DONE status=${spawnResult?.status} signal=${spawnResult?.signal} error=${spawnResult?.error?.message || "none"}`); | ||
| const tmpExists = _existsSync(tmpFile); | ||
| debugLog(`syncClient.socketRequestSync tmpFile exists=${tmpExists}`); | ||
| if (tmpExists) { | ||
| const raw = _readFileSync(tmpFile, "utf-8"); | ||
| debugLog(`syncClient.socketRequestSync response raw=${raw.slice(0, 200)}`); | ||
| const response = JSON.parse(raw); | ||
| _unlinkSync(tmpFile); | ||
@@ -499,2 +535,3 @@ if (response.error) { | ||
| try { | ||
| debugLog(`syncClient.httpRequestSync curl START url=${url} method=${method}`); | ||
| const result = _execSync( | ||
@@ -507,2 +544,3 @@ `/usr/bin/curl -s -X POST -H "Content-Type: application/json" -d '${request.replace(/'/g, "\\'")}' "${url}"`, | ||
| ); | ||
| debugLog(`syncClient.httpRequestSync curl DONE len=${result?.length}`); | ||
| const response = JSON.parse(result); | ||
@@ -514,2 +552,3 @@ if (response.error) { | ||
| } catch (error) { | ||
| debugLog(`syncClient.httpRequestSync FAILED: ${error.message}`); | ||
| throw new Error(`Sync request failed: ${error.message}`); | ||
@@ -535,2 +574,3 @@ } | ||
| syncClient; | ||
| _checking = false; | ||
| originalExec = null; | ||
@@ -589,2 +629,7 @@ originalExecSync = null; | ||
| const callback = typeof args[args.length - 1] === "function" ? args.pop() : void 0; | ||
| debugLog(`cp.exec ENTER command=${command} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.exec SKIP (re-entrancy) command=${command}`); | ||
| return original(command, ...args, callback); | ||
| } | ||
| self.eventReporter.intercept("exec", command); | ||
@@ -605,4 +650,11 @@ self.checkPolicy("exec", command).then(() => { | ||
| const interceptedExecSync = function(command, options) { | ||
| self.eventReporter.intercept("exec", command); | ||
| debugLog(`cp.execSync ENTER command=${command} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.execSync SKIP (re-entrancy) command=${command}`); | ||
| return original(command, options); | ||
| } | ||
| self._checking = true; | ||
| try { | ||
| self.eventReporter.intercept("exec", command); | ||
| debugLog(`cp.execSync policy_check START command=${command}`); | ||
| const result = self.syncClient.request( | ||
@@ -612,2 +664,3 @@ "policy_check", | ||
| ); | ||
| debugLog(`cp.execSync policy_check DONE allowed=${result.allowed} command=${command}`); | ||
| if (!result.allowed) { | ||
@@ -620,2 +673,3 @@ throw new PolicyDeniedError(result.reason || "Operation denied by policy", { | ||
| } catch (error) { | ||
| debugLog(`cp.execSync policy_check ERROR: ${error.message} command=${command}`); | ||
| if (error instanceof PolicyDeniedError) { | ||
@@ -627,3 +681,6 @@ throw error; | ||
| } | ||
| } finally { | ||
| self._checking = false; | ||
| } | ||
| debugLog(`cp.execSync calling original command=${command}`); | ||
| return original(command, options); | ||
@@ -637,2 +694,8 @@ }; | ||
| const interceptedSpawn = function(command, args, options) { | ||
| const fullCmd = args ? `${command} ${args.join(" ")}` : command; | ||
| debugLog(`cp.spawn ENTER command=${fullCmd} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.spawn SKIP (re-entrancy) command=${fullCmd}`); | ||
| return original(command, args, options || {}); | ||
| } | ||
| const fullCommand = args ? `${command} ${args.join(" ")}` : command; | ||
@@ -652,4 +715,11 @@ self.eventReporter.intercept("exec", fullCommand); | ||
| const fullCommand = args ? `${command} ${args.join(" ")}` : command; | ||
| self.eventReporter.intercept("exec", fullCommand); | ||
| debugLog(`cp.spawnSync ENTER command=${fullCommand} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`cp.spawnSync SKIP (re-entrancy) command=${fullCommand}`); | ||
| return original(command, args, options); | ||
| } | ||
| self._checking = true; | ||
| try { | ||
| self.eventReporter.intercept("exec", fullCommand); | ||
| debugLog(`cp.spawnSync policy_check START command=${fullCommand}`); | ||
| const result = self.syncClient.request( | ||
@@ -659,2 +729,3 @@ "policy_check", | ||
| ); | ||
| debugLog(`cp.spawnSync policy_check DONE allowed=${result.allowed} command=${fullCommand}`); | ||
| if (!result.allowed) { | ||
@@ -672,2 +743,3 @@ return { | ||
| } catch (error) { | ||
| debugLog(`cp.spawnSync policy_check ERROR: ${error.message} command=${fullCommand}`); | ||
| if (!self.failOpen) { | ||
@@ -684,3 +756,6 @@ return { | ||
| } | ||
| } finally { | ||
| self._checking = false; | ||
| } | ||
| debugLog(`cp.spawnSync calling original command=${fullCommand}`); | ||
| return original(command, args, options); | ||
@@ -693,2 +768,5 @@ }; | ||
| return function interceptedExecFile(file, ...args) { | ||
| if (self._checking) { | ||
| return original(file, ...args); | ||
| } | ||
| self.eventReporter.intercept("exec", file); | ||
@@ -705,2 +783,5 @@ self.checkPolicy("exec", file).catch((error) => { | ||
| const interceptedFork = function(modulePath, args, options) { | ||
| if (self._checking) { | ||
| return original(modulePath, args, options); | ||
| } | ||
| const pathStr = modulePath.toString(); | ||
@@ -718,2 +799,3 @@ self.eventReporter.intercept("exec", `fork:${pathStr}`); | ||
| // libs/shield-interceptor/src/interceptors/fs.ts | ||
| var import_node_url = require("node:url"); | ||
| var fsModule = require("node:fs"); | ||
@@ -733,5 +815,19 @@ var fsPromisesModule = require("node:fs/promises"); | ||
| } | ||
| function normalizePathArg(p) { | ||
| if (p instanceof URL) { | ||
| return (0, import_node_url.fileURLToPath)(p); | ||
| } | ||
| const s = p.toString(); | ||
| if (s.startsWith("file://")) { | ||
| try { | ||
| return (0, import_node_url.fileURLToPath)(new URL(s)); | ||
| } catch { | ||
| } | ||
| } | ||
| return s; | ||
| } | ||
| var FsInterceptor = class extends BaseInterceptor { | ||
| syncClient; | ||
| originals = /* @__PURE__ */ new Map(); | ||
| _checking = false; | ||
| constructor(options) { | ||
@@ -792,8 +888,16 @@ super(options); | ||
| safeOverride(module2, methodName, function intercepted(path, ...args) { | ||
| const pathString = path.toString(); | ||
| const pathString = normalizePathArg(path); | ||
| const callback = typeof args[args.length - 1] === "function" ? args.pop() : void 0; | ||
| debugLog(`fs.${methodName} ENTER (async) path=${pathString} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`fs.${methodName} SKIP (re-entrancy, async) path=${pathString}`); | ||
| original.call(module2, path, ...args, callback); | ||
| return; | ||
| } | ||
| self.eventReporter.intercept(operation, pathString); | ||
| self.checkPolicy(operation, pathString).then(() => { | ||
| debugLog(`fs.${methodName} policy OK (async) path=${pathString}`); | ||
| original.call(module2, path, ...args, callback); | ||
| }).catch((error) => { | ||
| debugLog(`fs.${methodName} policy ERROR (async): ${error.message} path=${pathString}`); | ||
| if (callback) { | ||
@@ -812,5 +916,12 @@ callback(error); | ||
| safeOverride(module2, methodName, function interceptedSync(path, ...args) { | ||
| const pathString = path.toString(); | ||
| self.eventReporter.intercept(operation, pathString); | ||
| const pathString = normalizePathArg(path); | ||
| debugLog(`fs.${methodName} ENTER path=${pathString} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`fs.${methodName} SKIP (re-entrancy) path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
| } | ||
| self._checking = true; | ||
| try { | ||
| self.eventReporter.intercept(operation, pathString); | ||
| debugLog(`fs.${methodName} policy_check START path=${pathString}`); | ||
| const result = self.syncClient.request( | ||
@@ -820,2 +931,3 @@ "policy_check", | ||
| ); | ||
| debugLog(`fs.${methodName} policy_check DONE allowed=${result.allowed} path=${pathString}`); | ||
| if (!result.allowed) { | ||
@@ -828,2 +940,3 @@ throw new PolicyDeniedError(result.reason || "Operation denied by policy", { | ||
| } catch (error) { | ||
| debugLog(`fs.${methodName} policy_check ERROR: ${error.message} path=${pathString}`); | ||
| if (error instanceof PolicyDeniedError) { | ||
@@ -835,3 +948,6 @@ throw error; | ||
| } | ||
| } finally { | ||
| self._checking = false; | ||
| } | ||
| debugLog(`fs.${methodName} calling original path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
@@ -847,5 +963,11 @@ }); | ||
| safeOverride(module2, methodName, async function interceptedPromise(path, ...args) { | ||
| const pathString = path.toString(); | ||
| const pathString = normalizePathArg(path); | ||
| debugLog(`fsPromises.${methodName} ENTER path=${pathString} _checking=${self._checking}`); | ||
| if (self._checking) { | ||
| debugLog(`fsPromises.${methodName} SKIP (re-entrancy) path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
| } | ||
| self.eventReporter.intercept(operation, pathString); | ||
| await self.checkPolicy(operation, pathString); | ||
| debugLog(`fsPromises.${methodName} policy OK path=${pathString}`); | ||
| return original.call(module2, path, ...args); | ||
@@ -852,0 +974,0 @@ }); |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances in 1 package
172353
12.59%42
5%4496
9.02%9
-10%+ Added
- Removed
Updated