@secure-exec/core 0.1.1-rc.2 → 0.1.1-rc.3

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.
@@ -80,6 +80,21 @@ export const NODE_CUSTOM_GLOBAL_INVENTORY = [
80
80
  classification: "hardened",
81
81
  rationale: "Host-to-sandbox HTTP server dispatch entrypoint.",
82
82
  },
83
+ {
84
+ name: "_httpServerUpgradeDispatch",
85
+ classification: "hardened",
86
+ rationale: "Host-to-sandbox HTTP server upgrade dispatch entrypoint.",
87
+ },
88
+ {
89
+ name: "_upgradeSocketData",
90
+ classification: "hardened",
91
+ rationale: "Host-to-sandbox upgrade socket data push entrypoint.",
92
+ },
93
+ {
94
+ name: "_upgradeSocketEnd",
95
+ classification: "hardened",
96
+ rationale: "Host-to-sandbox upgrade socket end push entrypoint.",
97
+ },
83
98
  {
84
99
  name: "ProcessExitError",
85
100
  classification: "hardened",
@@ -125,6 +140,71 @@ export const NODE_CUSTOM_GLOBAL_INVENTORY = [
125
140
  classification: "hardened",
126
141
  rationale: "Host entropy bridge reference for crypto.randomUUID.",
127
142
  },
143
+ {
144
+ name: "_cryptoHashDigest",
145
+ classification: "hardened",
146
+ rationale: "Host crypto bridge reference for createHash digest computation.",
147
+ },
148
+ {
149
+ name: "_cryptoHmacDigest",
150
+ classification: "hardened",
151
+ rationale: "Host crypto bridge reference for createHmac digest computation.",
152
+ },
153
+ {
154
+ name: "_cryptoPbkdf2",
155
+ classification: "hardened",
156
+ rationale: "Host crypto bridge reference for pbkdf2 key derivation.",
157
+ },
158
+ {
159
+ name: "_cryptoScrypt",
160
+ classification: "hardened",
161
+ rationale: "Host crypto bridge reference for scrypt key derivation.",
162
+ },
163
+ {
164
+ name: "_cryptoCipheriv",
165
+ classification: "hardened",
166
+ rationale: "Host crypto bridge reference for createCipheriv encryption.",
167
+ },
168
+ {
169
+ name: "_cryptoDecipheriv",
170
+ classification: "hardened",
171
+ rationale: "Host crypto bridge reference for createDecipheriv decryption.",
172
+ },
173
+ {
174
+ name: "_cryptoCipherivCreate",
175
+ classification: "hardened",
176
+ rationale: "Host crypto bridge reference for stateful cipher/decipher creation.",
177
+ },
178
+ {
179
+ name: "_cryptoCipherivUpdate",
180
+ classification: "hardened",
181
+ rationale: "Host crypto bridge reference for stateful cipher/decipher update.",
182
+ },
183
+ {
184
+ name: "_cryptoCipherivFinal",
185
+ classification: "hardened",
186
+ rationale: "Host crypto bridge reference for stateful cipher/decipher final.",
187
+ },
188
+ {
189
+ name: "_cryptoSign",
190
+ classification: "hardened",
191
+ rationale: "Host crypto bridge reference for sign operations.",
192
+ },
193
+ {
194
+ name: "_cryptoVerify",
195
+ classification: "hardened",
196
+ rationale: "Host crypto bridge reference for verify operations.",
197
+ },
198
+ {
199
+ name: "_cryptoGenerateKeyPairSync",
200
+ classification: "hardened",
201
+ rationale: "Host crypto bridge reference for generateKeyPairSync.",
202
+ },
203
+ {
204
+ name: "_cryptoSubtle",
205
+ classification: "hardened",
206
+ rationale: "Host crypto bridge reference for Web Crypto subtle operations.",
207
+ },
128
208
  {
129
209
  name: "_fsReadFile",
130
210
  classification: "hardened",
@@ -275,6 +355,21 @@ export const NODE_CUSTOM_GLOBAL_INVENTORY = [
275
355
  classification: "hardened",
276
356
  rationale: "Host network bridge reference.",
277
357
  },
358
+ {
359
+ name: "_upgradeSocketWriteRaw",
360
+ classification: "hardened",
361
+ rationale: "Host upgrade socket write bridge reference.",
362
+ },
363
+ {
364
+ name: "_upgradeSocketEndRaw",
365
+ classification: "hardened",
366
+ rationale: "Host upgrade socket end bridge reference.",
367
+ },
368
+ {
369
+ name: "_upgradeSocketDestroyRaw",
370
+ classification: "hardened",
371
+ rationale: "Host upgrade socket destroy bridge reference.",
372
+ },
278
373
  {
279
374
  name: "_ptySetRawMode",
280
375
  classification: "hardened",
@@ -229,6 +229,22 @@ export function wrapNetworkAdapter(adapter, permissions) {
229
229
  checkPermission(permissions?.network, { op: "http", url, method: options?.method }, (req, reason) => createEaccesError("connect", req.url, reason));
230
230
  return adapter.httpRequest(url, options);
231
231
  },
232
+ // Forward upgrade socket methods for bidirectional WebSocket relay
233
+ upgradeSocketWrite: adapter.upgradeSocketWrite?.bind(adapter),
234
+ upgradeSocketEnd: adapter.upgradeSocketEnd?.bind(adapter),
235
+ upgradeSocketDestroy: adapter.upgradeSocketDestroy?.bind(adapter),
236
+ setUpgradeSocketCallbacks: adapter.setUpgradeSocketCallbacks?.bind(adapter),
237
+ // Forward TCP socket (net module) methods with permission check on connect
238
+ netSocketConnect: adapter.netSocketConnect
239
+ ? (host, port, callbacks) => {
240
+ checkPermission(permissions?.network, { op: "connect", hostname: host, port }, (req, reason) => createEaccesError("connect", `${req.hostname}:${req.port}`, reason));
241
+ return adapter.netSocketConnect(host, port, callbacks);
242
+ }
243
+ : undefined,
244
+ netSocketWrite: adapter.netSocketWrite?.bind(adapter),
245
+ netSocketEnd: adapter.netSocketEnd?.bind(adapter),
246
+ netSocketDestroy: adapter.netSocketDestroy?.bind(adapter),
247
+ netSocketUpgradeTls: adapter.netSocketUpgradeTls?.bind(adapter),
232
248
  };
233
249
  }
234
250
  /** Wrap a CommandExecutor so spawn passes through the childProcess permission check. */
package/dist/types.d.ts CHANGED
@@ -132,12 +132,24 @@ export interface NetworkServerListenOptions {
132
132
  port?: number;
133
133
  hostname?: string;
134
134
  onRequest(request: NetworkServerRequest): Promise<NetworkServerResponse> | NetworkServerResponse;
135
+ /** Called when an HTTP upgrade request arrives (e.g. WebSocket). */
136
+ onUpgrade?(request: NetworkServerRequest, head: string, socketId: number): void;
137
+ /** Called when the real upgrade socket receives data from the remote peer. */
138
+ onUpgradeSocketData?(socketId: number, dataBase64: string): void;
139
+ /** Called when the real upgrade socket closes. */
140
+ onUpgradeSocketEnd?(socketId: number): void;
135
141
  }
136
142
  export interface NetworkAdapter {
137
143
  httpServerListen?(options: NetworkServerListenOptions): Promise<{
138
144
  address: NetworkServerAddress | null;
139
145
  }>;
140
146
  httpServerClose?(serverId: number): Promise<void>;
147
+ /** Write data from the sandbox to a real upgrade socket on the host. */
148
+ upgradeSocketWrite?(socketId: number, dataBase64: string): void;
149
+ /** End a real upgrade socket on the host. */
150
+ upgradeSocketEnd?(socketId: number): void;
151
+ /** Destroy a real upgrade socket on the host. */
152
+ upgradeSocketDestroy?(socketId: number): void;
141
153
  fetch(url: string, options: {
142
154
  method?: string;
143
155
  headers?: Record<string, string>;
@@ -170,7 +182,35 @@ export interface NetworkAdapter {
170
182
  body: string;
171
183
  url: string;
172
184
  trailers?: Record<string, string>;
185
+ upgradeSocketId?: number;
173
186
  }>;
187
+ /** Register callbacks for client-side upgrade socket data push. */
188
+ setUpgradeSocketCallbacks?(callbacks: {
189
+ onData: (socketId: number, dataBase64: string) => void;
190
+ onEnd: (socketId: number) => void;
191
+ }): void;
192
+ /** Create a TCP socket and connect to host:port. Returns a socketId. */
193
+ netSocketConnect?(host: string, port: number, callbacks: {
194
+ onConnect: () => void;
195
+ onData: (dataBase64: string) => void;
196
+ onEnd: () => void;
197
+ onError: (message: string) => void;
198
+ onClose: (hadError: boolean) => void;
199
+ }): number;
200
+ /** Write data to a TCP socket. */
201
+ netSocketWrite?(socketId: number, dataBase64: string): void;
202
+ /** End a TCP socket (half-close). */
203
+ netSocketEnd?(socketId: number): void;
204
+ /** Destroy a TCP socket. */
205
+ netSocketDestroy?(socketId: number): void;
206
+ /** Upgrade an existing TCP socket to TLS. */
207
+ netSocketUpgradeTls?(socketId: number, optionsJson: string, callbacks: {
208
+ onData: (dataBase64: string) => void;
209
+ onEnd: () => void;
210
+ onError: (message: string) => void;
211
+ onClose: (hadError: boolean) => void;
212
+ onSecureConnect: () => void;
213
+ }): void;
174
214
  }
175
215
  export interface PermissionDecision {
176
216
  allow: boolean;
@@ -182,10 +222,11 @@ export interface FsAccessRequest {
182
222
  path: string;
183
223
  }
184
224
  export interface NetworkAccessRequest {
185
- op: "fetch" | "http" | "dns" | "listen";
225
+ op: "fetch" | "http" | "dns" | "listen" | "connect";
186
226
  url?: string;
187
227
  method?: string;
188
228
  hostname?: string;
229
+ port?: number;
189
230
  }
190
231
  export interface ChildProcessAccessRequest {
191
232
  command: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secure-exec/core",
3
- "version": "0.1.1-rc.2",
3
+ "version": "0.1.1-rc.3",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.js",