Skip to content

Commit 9183a64

Browse files
committed
pr feedback:
- change how we allow or block modules - change how allowed imports are handled - exported more types - added build step to a script
1 parent e3703f0 commit 9183a64

4 files changed

Lines changed: 37 additions & 75 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
"check:eslint": "npm run build:dts && ESLINT_USE_FLAT_CONFIG=false eslint -v && ESLINT_USE_FLAT_CONFIG=false eslint --max-warnings=0 --ext '.js,.ts' src test",
139139
"check:tsd": "tsd --version && tsd",
140140
"check:dependencies": "npm run build:bundle && mocha test/action/dependency.test.ts",
141-
"check:dts": "node ./node_modules/typescript/bin/tsc --target es2023 --module commonjs --noEmit mongodb.d.ts && tsd",
141+
"check:dts": "npm run build:bundle && node ./node_modules/typescript/bin/tsc --target es2023 --module commonjs --noEmit mongodb.d.ts && tsd",
142142
"check:search-indexes": "npm run build:bundle && nyc mocha --config test/mocha_mongodb.js test/manual/search-index-management.prose.test.ts",
143143
"check:test": "npm run build:bundle && nyc mocha --config test/mocha_mongodb.js test/integration",
144144
"check:test-bundled": "MONGODB_BUNDLED=true npm run check:test",

src/runtime_adapters.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* eslint-disable no-restricted-imports, @typescript-eslint/no-require-imports */
1+
/* eslint-disable no-restricted-imports*/
22

33
// We squash the restricted import errors here because we are using type-only imports, which
44
// do not impact the driver's actual runtime dependencies.
@@ -43,7 +43,9 @@ export interface Runtime {
4343
* not provided by in `options`, and returns a `Runtime`.
4444
*/
4545
export function resolveRuntimeAdapters(options: MongoClientOptions): Runtime {
46+
const correctRequire = (globalThis as any).__driver_require || require;
47+
4648
return {
47-
os: options.runtimeAdapters?.os ?? require('os')
49+
os: options.runtimeAdapters?.os ?? correctRequire('os')
4850
};
4951
}

test/mongodb_bundled.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ export type {
385385
Document,
386386
DriverInfo,
387387
Filter,
388+
FindOptions,
388389
IndexDirection,
389390
InferIdType,
390391
KMSProviders,
@@ -449,6 +450,7 @@ import type {
449450
MongoClient as _MongoClient,
450451
MongoCredentials as _MongoCredentials,
451452
MongoError as _MongoError,
453+
ObjectId as _ObjectId,
452454
OnDemandDocument as _OnDemandDocument,
453455
Server as _Server,
454456
ServerApiVersion as _ServerApiVersion,
@@ -506,6 +508,7 @@ export type HostAddress = _HostAddress;
506508
export type MongoClient = _MongoClient;
507509
export type MongoCredentials = _MongoCredentials;
508510
export type MongoError = _MongoError;
511+
export type ObjectId = _ObjectId;
509512
export type OnDemandDocument = _OnDemandDocument;
510513
export type Server = _Server;
511514
export type ServerApiVersion = _ServerApiVersion;

test/tools/runner/vm_context_helper.ts

Lines changed: 29 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,37 @@
22

33
import * as fs from 'node:fs';
44
import { isBuiltin } from 'node:module';
5-
import { platform } from 'node:os';
65
import * as path from 'node:path';
76
import * as vm from 'node:vm';
87

8+
const allowedModules = new Set([
9+
'@aws-sdk/credential-providers',
10+
'@mongodb-js/saslprep',
11+
'@mongodb-js/zstd',
12+
'bson',
13+
'gcp-metadata',
14+
'kerberos',
15+
'mongodb-client-encryption',
16+
'mongodb-connection-string-url',
17+
'path',
18+
'snappy'
19+
]);
20+
const blockedModules = new Set(['os']);
21+
922
/**
1023
* Creates a require function that blocks access to specified core modules
1124
*/
1225
function createRestrictedRequire() {
13-
const blockedModules = new Set(['os']);
14-
const allowedRequesters = [
15-
{
16-
file: 'runtime_adapters.ts',
17-
method: 'resolveRuntimeAdapters',
18-
module: 'os'
19-
}
20-
];
21-
2226
return function restrictedRequire(moduleName: string) {
23-
// Block core modules
24-
if (isBuiltin(moduleName) && blockedModules.has(moduleName)) {
25-
const callStack = new Error().stack;
26-
const correctPath = platform() === 'win32' ? path.win32 : path.posix;
27-
const methodAndFile = callStack.split('\n')[2];
28-
const match = methodAndFile.match(/at (.*) \((.*)\)/);
29-
const method = match ? match[1] : null;
30-
const sourceFileAndLineNumbers = match ? match[2] : 'unknown';
31-
const sourceFile =
32-
sourceFileAndLineNumbers.indexOf('.ts:') === -1
33-
? sourceFileAndLineNumbers
34-
: sourceFileAndLineNumbers.substring(0, sourceFileAndLineNumbers.lastIndexOf('.ts:') + 3);
35-
const sourceFileName = correctPath.basename(sourceFile);
36-
const isAllowed = allowedRequesters.some(
37-
requester =>
38-
requester.file === sourceFileName &&
39-
requester.method === method &&
40-
requester.module === moduleName
41-
);
42-
43-
if (isAllowed) {
44-
// Allow access to the module if the requester is in the allowlist
45-
} else {
46-
throw new Error(
47-
`Access to core module '${moduleName}' from ${sourceFileName} is restricted in this context`
48-
);
49-
}
27+
const isModuleBuiltin = isBuiltin(moduleName);
28+
const isModuleAllowed = allowedModules.has(moduleName);
29+
const isModuleBlocked = blockedModules.has(moduleName);
30+
const shouldAllow = isModuleAllowed || isModuleBuiltin;
31+
const shouldBlock = isModuleBlocked || !shouldAllow;
32+
33+
if (shouldBlock) {
34+
throw new Error(`Access to core module '${moduleName}' is restricted in this context`);
5035
}
51-
5236
return require(moduleName);
5337
} as NodeRequire;
5438
}
@@ -77,52 +61,25 @@ const sandbox = vm.createContext({
7761
// Process
7862
process: process,
7963

64+
// TODO: NODE-7460 - Remove Error and other unnecessary exports
65+
8066
// Global objects needed for runtime
8167
Buffer: Buffer,
8268
Headers: global.Headers,
83-
Promise: Promise,
8469
Map: Map,
85-
Set: Set,
86-
WeakMap: WeakMap,
87-
WeakSet: WeakSet,
88-
ArrayBuffer: ArrayBuffer,
89-
SharedArrayBuffer: SharedArrayBuffer,
90-
Atomics: Atomics,
91-
DataView: DataView,
92-
Int8Array: Int8Array,
93-
Uint8Array: Uint8Array,
94-
Uint8ClampedArray: Uint8ClampedArray,
95-
Int16Array: Int16Array,
96-
Uint16Array: Uint16Array,
97-
Int32Array: Int32Array,
98-
Uint32Array: Uint32Array,
99-
Float32Array: Float32Array,
100-
Float64Array: Float64Array,
101-
BigInt64Array: BigInt64Array,
102-
BigUint64Array: BigUint64Array,
103-
104-
// Other necessary globals
70+
Promise: Promise,
71+
Math: Math,
10572
TextEncoder: global.TextEncoder,
10673
TextDecoder: global.TextDecoder,
10774
BigInt: global.BigInt,
108-
Symbol: Symbol,
109-
Proxy: Proxy,
110-
Reflect: Reflect,
111-
Object: Object,
112-
Array: Array,
113-
Function: Function,
114-
String: String,
115-
Number: Number,
116-
Boolean: Boolean,
117-
RegExp: RegExp,
118-
Math: Math,
119-
JSON: JSON,
120-
Intl: global.Intl,
12175
crypto: global.crypto,
12276

12377
// Custom require that blocks core modules
12478
require: createRestrictedRequire(),
12579

80+
// Driver require
81+
__driver_require: require,
82+
12683
// Needed for some modules
12784
global: undefined as any,
12885
globalThis: undefined as any

0 commit comments

Comments
 (0)