fix: handle additional context root paths for node-vm#6491
fix: handle additional context root paths for node-vm#6491bijin-bruno merged 3 commits intousebruno:mainfrom
additional context root paths for node-vm#6491Conversation
WalkthroughCompute and normalize absolute additional context roots (always include collectionPath), normalize module names for Windows separators, pass normalized roots through the custom require/load flow, validate resolved local-module paths against all allowed roots and throw detailed errors when outside, and add Jest tests covering these behaviors. Changes
Sequence Diagram(s)sequenceDiagram
actor Script
participant VM as node-vm Sandbox
participant Resolver as Module Resolver
participant Validator as Context Validator
participant FS as Filesystem
Script->>VM: execute script / call require('name')
VM->>Resolver: resolveModule(name, requesterPath, additionalContextRootsAbsolute)
Resolver->>Resolver: normalize name (backslashes → forward slashes)
alt local path (./, ../, or backslash form)
Resolver->>Validator: toAbsolutePath(normalized, requesterPath)
rect rgb(235,245,255)
Note over Validator: Check absolute path against allowed roots
Validator->>Validator: compare against collectionPath + additionalContextRootsAbsolute
end
alt allowed
Validator->>FS: read file / load module
FS-->>Resolver: module exports
else blocked
Validator-->>Resolver: throw Error(listAllowedRoots + hint about additionalContextRoots)
end
else non-local (npm or builtin)
Resolver->>FS: standard node resolution (node_modules)
FS-->>Resolver: module exports
end
Resolver-->>VM: module exports or error
VM-->>Script: return value or throw
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
additional context root paths for node vmadditional context root paths for node-vm
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (4)
packages/bruno-js/src/sandbox/node-vm/index.js (3)
203-215: Redundant normalization on line 204.
additionalContextRootsAbsoluteentries are already normalized at lines 123-126. Thepath.normalize(allowedRoot)call on line 204 is redundant.🔎 Proposed simplification
const isWithinAllowedRoot = additionalContextRootsAbsolute.some((allowedRoot) => { - const normalizedAllowedRoot = path.normalize(allowedRoot); - const relativePath = path.relative(normalizedAllowedRoot, normalizedFilePath); + const relativePath = path.relative(allowedRoot, normalizedFilePath); return !relativePath.startsWith('..') && !path.isAbsolute(relativePath); });
187-194: JSDoc incomplete: missing@throwsfor out-of-root access.The JSDoc at line 185 mentions throwing when "module is outside collection path," but the actual error message now references "allowed context roots." Consider updating the JSDoc to reflect this.
🔎 Proposed JSDoc update
- * @throws {Error} When module is outside collection path or cannot be loaded + * @throws {Error} When module is outside allowed context roots or cannot be loaded
243-250: NestedcreateCustomRequirerecomputesadditionalContextRootsAbsoluteon each local module load.This is inefficient for deeply nested local imports. Consider passing the already-computed
additionalContextRootsAbsolutearray to avoid redundant path resolution and normalization on every nested require.🔎 Proposed fix
First, update
loadLocalModuleto receive the computed roots:function loadLocalModule({ moduleName, collectionPath, scriptContext, localModuleCache, currentModuleDir, - additionalContextRootsAbsolute = [] + additionalContextRootsAbsolute = [], + scriptingConfig }) {Then update the nested
createCustomRequire:require: createCustomRequire({ - scriptingConfig: scriptContext.scriptingConfig || {}, + scriptingConfig: scriptingConfig, collectionPath, scriptContext, currentModuleDir: moduleDir, localModuleCache, - allowScriptFilesystemAccess: get(scriptContext.scriptingConfig, 'filesystemAccess.allow', false) + allowScriptFilesystemAccess: get(scriptingConfig, 'filesystemAccess.allow', false) })And pass
scriptingConfigfromloadLocalModulecall site at line 132.packages/bruno-js/src/sandbox/node-vm/index.spec.js (1)
186-209: Caching test doesn't truly verify caching behavior.The test writes a static module with
count: 1and checksmod1.count === mod2.count. This will always be true since the file content is fixed. The test doesn't verify that the module code executed only once.A more robust test would use a side-effect (e.g., incrementing a counter in context) to prove the module wasn't re-executed.
🔎 Suggested improvement
it('should cache loaded modules', async () => { fs.writeFileSync( path.join(collectionPath, 'cached.js'), ` bru.incrementCount(); module.exports = { loaded: true }; ` ); let loadCount = 0; const context = { bru: { setVar: jest.fn(), incrementCount: () => { loadCount++; } }, console: console }; const script = ` const mod1 = require('./cached'); const mod2 = require('./cached'); bru.setVar('same', mod1 === mod2); `; await runScriptInNodeVm({ script, context, collectionPath, scriptingConfig: {} }); expect(loadCount).toBe(1); // Module executed only once expect(context.bru.setVar).toHaveBeenCalledWith('same', true); });
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/bruno-js/src/sandbox/node-vm/index.jspackages/bruno-js/src/sandbox/node-vm/index.spec.js
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (CODING_STANDARDS.md)
**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions.() => {}is good
No space between function name and parentheses.func()notfunc ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly
Files:
packages/bruno-js/src/sandbox/node-vm/index.spec.jspackages/bruno-js/src/sandbox/node-vm/index.js
🧠 Learnings (3)
📚 Learning: 2025-12-05T20:31:33.005Z
Learnt from: CR
Repo: usebruno/bruno PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-12-05T20:31:33.005Z
Learning: Applies to **/*.test.{js,jsx,ts,tsx} : Add tests for any new functionality or meaningful changes. If code is added, removed, or significantly modified, corresponding tests should be updated or created
Applied to files:
packages/bruno-js/src/sandbox/node-vm/index.spec.js
📚 Learning: 2025-12-16T07:16:23.647Z
Learnt from: sanish-bruno
Repo: usebruno/bruno PR: 6090
File: tests/scripting/hooks/init-user-data/ui-state-snapshot.json:1-8
Timestamp: 2025-12-16T07:16:23.647Z
Learning: For e2e tests in the bruno repository: Collections that are shared between CLI and UI tests (comprehensive test suites testing core functionality) should be placed in `packages/bruno-tests/` to avoid duplication. The `tests/**/fixtures/collection` pattern should be used for test-specific collections that test particular UI behaviors or are specific to a single test file.
Applied to files:
packages/bruno-js/src/sandbox/node-vm/index.spec.js
📚 Learning: 2025-12-17T21:41:24.730Z
Learnt from: naman-bruno
Repo: usebruno/bruno PR: 6407
File: packages/bruno-app/src/components/Environments/ConfirmCloseEnvironment/index.js:5-41
Timestamp: 2025-12-17T21:41:24.730Z
Learning: Do not suggest PropTypes validation for React components in the Bruno codebase. The project does not use PropTypes, so reviews should avoid proposing PropTypes and rely on the existing typing/validation approach (e.g., TypeScript or alternative runtime checks) if applicable. This guideline applies broadly to all JavaScript/JSX components in the repo.
Applied to files:
packages/bruno-js/src/sandbox/node-vm/index.spec.jspackages/bruno-js/src/sandbox/node-vm/index.js
🧬 Code graph analysis (1)
packages/bruno-js/src/sandbox/node-vm/index.js (4)
packages/bruno-js/src/sandbox/node-vm/index.spec.js (2)
path(3-3)collectionPath(9-9)packages/bruno-cli/src/runner/run-single-request.js (1)
path(19-19)packages/bruno-electron/src/ipc/network/index.js (2)
path(3-3)collectionPath(338-338)packages/bruno-cli/src/commands/run.js (2)
path(3-3)collectionPath(295-295)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Playwright E2E Tests
- GitHub Check: Unit Tests
- GitHub Check: CLI Tests
- GitHub Check: SSL Tests - macOS
- GitHub Check: SSL Tests - Windows
- GitHub Check: SSL Tests - Linux
🔇 Additional comments (5)
packages/bruno-js/src/sandbox/node-vm/index.js (1)
129-133: LGTM - Windows path normalization is correct.The normalization to forward slashes before checking for
./and../prefixes properly handles cross-platform path separators. This ensures local module detection works on Windows.packages/bruno-js/src/sandbox/node-vm/index.spec.js (4)
11-21: LGTM - Good test isolation with temp directories.Proper setup and teardown using
mkdtempSyncandrmSyncensures tests don't pollute each other or leave artifacts. Clean pattern for filesystem-based testing.
74-94: LGTM - Windows backslash test is well-designed.The double-escaped backslash in the script string (
'.\\\\module') correctly simulates how a Windows path would appear in a JavaScript string. Good cross-platform coverage.
167-183: LGTM - npm module loading test is appropriate.Testing that
lodash.getis a function confirms the require resolution throughmodule.pathsworks correctly.
96-106: Add test for symlink-based path traversal escapes.The path validation uses
path.normalize()andpath.relative()but does not resolve symlinks withfs.realpathSync(). A symlink created inside the collection directory pointing outside can bypass the boundary check. For example, a symlink atcollection/link → /outside/filewould pass validation (appears to be within collection) but the actual loaded module is outside the sandbox.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
packages/bruno-js/src/sandbox/node-vm/index.js (1)
121-126: Security gap: nestedcreateCustomRequirerecomputes allowed roots instead of inheriting them.The nested
createCustomRequirecall at line 244 derivesadditionalContextRootsAbsolutefromscriptContext.scriptingConfig || {}rather than accepting the already-computed and validated array. IfscriptContext.scriptingConfigdiffers or is manipulated, nested modules could load from unexpected paths.Pass
additionalContextRootsAbsoluteas an explicit parameter tocreateCustomRequireand propagate it to nested calls.🔎 Proposed fix
Update
createCustomRequiresignature to accept pre-computed roots:function createCustomRequire({ scriptingConfig, collectionPath, scriptContext, currentModuleDir = collectionPath, localModuleCache = new Map(), - allowScriptFilesystemAccess = false + allowScriptFilesystemAccess = false, + additionalContextRootsAbsolute = null }) { - const additionalContextRoots = get(scriptingConfig, 'additionalContextRoots', []); - const additionalContextRootsAbsolute = lodash - .chain(additionalContextRoots) - .map((acr) => (path.isAbsolute(acr) ? acr : path.join(collectionPath, acr))) - .map((acr) => path.normalize(acr)) - .value(); - additionalContextRootsAbsolute.push(path.normalize(collectionPath)); + if (additionalContextRootsAbsolute === null) { + const additionalContextRoots = get(scriptingConfig, 'additionalContextRoots', []); + additionalContextRootsAbsolute = lodash + .chain(additionalContextRoots) + .map((acr) => (path.isAbsolute(acr) ? acr : path.join(collectionPath, acr))) + .map((acr) => path.normalize(acr)) + .value(); + additionalContextRootsAbsolute.push(path.normalize(collectionPath)); + }Then pass it through in nested call at line 244:
require: createCustomRequire({ scriptingConfig: scriptContext.scriptingConfig || {}, collectionPath, scriptContext, currentModuleDir: moduleDir, localModuleCache, - allowScriptFilesystemAccess: get(scriptContext.scriptingConfig, 'filesystemAccess.allow', false) + allowScriptFilesystemAccess: get(scriptContext.scriptingConfig, 'filesystemAccess.allow', false), + additionalContextRootsAbsolute })Also applies to: 244-251
🧹 Nitpick comments (1)
packages/bruno-js/src/sandbox/node-vm/index.js (1)
204-216: Solid security check with clear error messaging.The containment check using
path.relativecorrectly identifies when a file path escapes allowed roots. The!path.isAbsolute(relativePath)guard handles Windows cross-drive scenarios.Minor note: Line 205 re-normalizes
allowedRoot, but these are already normalized at line 124. You could remove the redundant normalization, but it's harmless.🔎 Optional: Remove redundant normalization
const isWithinAllowedRoot = additionalContextRootsAbsolute.some((allowedRoot) => { - const normalizedAllowedRoot = path.normalize(allowedRoot); - const relativePath = path.relative(normalizedAllowedRoot, normalizedFilePath); + const relativePath = path.relative(allowedRoot, normalizedFilePath); return !relativePath.startsWith('..') && !path.isAbsolute(relativePath); });
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/bruno-js/src/sandbox/node-vm/index.jspackages/bruno-js/src/sandbox/node-vm/index.spec.js
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/bruno-js/src/sandbox/node-vm/index.spec.js
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (CODING_STANDARDS.md)
**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions.() => {}is good
No space between function name and parentheses.func()notfunc ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly
Files:
packages/bruno-js/src/sandbox/node-vm/index.js
🧠 Learnings (1)
📚 Learning: 2025-12-17T21:41:24.730Z
Learnt from: naman-bruno
Repo: usebruno/bruno PR: 6407
File: packages/bruno-app/src/components/Environments/ConfirmCloseEnvironment/index.js:5-41
Timestamp: 2025-12-17T21:41:24.730Z
Learning: Do not suggest PropTypes validation for React components in the Bruno codebase. The project does not use PropTypes, so reviews should avoid proposing PropTypes and rely on the existing typing/validation approach (e.g., TypeScript or alternative runtime checks) if applicable. This guideline applies broadly to all JavaScript/JSX components in the repo.
Applied to files:
packages/bruno-js/src/sandbox/node-vm/index.js
🧬 Code graph analysis (1)
packages/bruno-js/src/sandbox/node-vm/index.js (4)
packages/bruno-js/src/sandbox/node-vm/index.spec.js (2)
path(3-3)collectionPath(9-9)packages/bruno-cli/src/runner/run-single-request.js (1)
path(19-19)packages/bruno-electron/src/ipc/network/index.js (2)
path(3-3)collectionPath(338-338)packages/bruno-cli/src/commands/run.js (2)
path(3-3)collectionPath(295-295)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Unit Tests
- GitHub Check: Playwright E2E Tests
- GitHub Check: CLI Tests
- GitHub Check: SSL Tests - macOS
- GitHub Check: SSL Tests - Windows
- GitHub Check: SSL Tests - Linux
🔇 Additional comments (2)
packages/bruno-js/src/sandbox/node-vm/index.js (2)
129-133: Good cross-platform path handling.Normalizing backslashes to forward slashes before the local module check ensures Windows-style paths (
.\fooor..\bar) are correctly identified as local modules. The normalized name is then passed through toloadLocalModule.
188-195: LGTM - parameter addition is well documented.The
additionalContextRootsAbsoluteparameter with[]default ensures deny-by-default behavior when no roots are provided. This is a safe default.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/bruno-js/src/sandbox/node-vm/index.spec.js (1)
226-251: Test validates caching but setup has a subtle issue.The
callCountincrement happens at test setup time (whenwriteFileSyncis called), not at module execution time. The test still validates caching correctly (same object reference viamod1.count === mod2.count), but the intent seems to be testing that the module code is executed only once. The current test logic works, but thecallCountvariable is unused after the initial assignment.🔎 Consider simplifying the test
describe('createCustomRequire - module caching', () => { it('should cache loaded modules', async () => { - let callCount = 0; fs.writeFileSync( path.join(collectionPath, 'cached.js'), - ` - module.exports = { count: ${++callCount} }; - ` + 'module.exports = { count: 1 };' ); const script = ` const mod1 = require('./cached'); const mod2 = require('./cached'); - bru.setVar('same', mod1.count === mod2.count); + bru.setVar('same', mod1 === mod2); `;packages/bruno-js/src/sandbox/node-vm/index.js (1)
168-176: Consider handling the case whereadditionalContextRootsAbsoluteis empty.The error message template handles the empty case with
|| ' - No "additionalContextRoots" defined', but sincecollectionPathis always pushed (line 48), the array should never be empty in practice. The fallback text is misleading because it suggests no roots are defined whencollectionPathis always included.🔎 Consider updating fallback message
- throw new Error(`Could not resolve module "${moduleName}": ${requireError.message}\n\nThis most likely means you did not install the module under the collection or the "additionalContextRoots" using a package manager like npm.\n\nThese are your current "additionalContextRoots":\n${additionalContextRootsAbsolute.map((root) => ` - ${root}`).join('\n') || ' - No "additionalContextRoots" defined'}`); + throw new Error(`Could not resolve module "${moduleName}": ${requireError.message}\n\nThis most likely means you did not install the module under the collection or the "additionalContextRoots" using a package manager like npm.\n\nThese are your current allowed context roots:\n${additionalContextRootsAbsolute.map((root) => ` - ${root}`).join('\n')}`);
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/bruno-js/src/sandbox/node-vm/index.jspackages/bruno-js/src/sandbox/node-vm/index.spec.js
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (CODING_STANDARDS.md)
**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions.() => {}is good
No space between function name and parentheses.func()notfunc ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly
Files:
packages/bruno-js/src/sandbox/node-vm/index.spec.jspackages/bruno-js/src/sandbox/node-vm/index.js
🧠 Learnings (3)
📚 Learning: 2025-12-05T20:31:33.005Z
Learnt from: CR
Repo: usebruno/bruno PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-12-05T20:31:33.005Z
Learning: Applies to **/*.test.{js,jsx,ts,tsx} : Add tests for any new functionality or meaningful changes. If code is added, removed, or significantly modified, corresponding tests should be updated or created
Applied to files:
packages/bruno-js/src/sandbox/node-vm/index.spec.js
📚 Learning: 2025-12-16T07:16:23.647Z
Learnt from: sanish-bruno
Repo: usebruno/bruno PR: 6090
File: tests/scripting/hooks/init-user-data/ui-state-snapshot.json:1-8
Timestamp: 2025-12-16T07:16:23.647Z
Learning: For e2e tests in the bruno repository: Collections that are shared between CLI and UI tests (comprehensive test suites testing core functionality) should be placed in `packages/bruno-tests/` to avoid duplication. The `tests/**/fixtures/collection` pattern should be used for test-specific collections that test particular UI behaviors or are specific to a single test file.
Applied to files:
packages/bruno-js/src/sandbox/node-vm/index.spec.js
📚 Learning: 2025-12-17T21:41:24.730Z
Learnt from: naman-bruno
Repo: usebruno/bruno PR: 6407
File: packages/bruno-app/src/components/Environments/ConfirmCloseEnvironment/index.js:5-41
Timestamp: 2025-12-17T21:41:24.730Z
Learning: Do not suggest PropTypes validation for React components in the Bruno codebase. The project does not use PropTypes, so reviews should avoid proposing PropTypes and rely on the existing typing/validation approach (e.g., TypeScript or alternative runtime checks) if applicable. This guideline applies broadly to all JavaScript/JSX components in the repo.
Applied to files:
packages/bruno-js/src/sandbox/node-vm/index.spec.jspackages/bruno-js/src/sandbox/node-vm/index.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: SSL Tests - Windows
- GitHub Check: SSL Tests - Linux
- GitHub Check: SSL Tests - macOS
- GitHub Check: Playwright E2E Tests
- GitHub Check: CLI Tests
- GitHub Check: Unit Tests
🔇 Additional comments (16)
packages/bruno-js/src/sandbox/node-vm/index.spec.js (10)
1-6: LGTM!Imports are clean and appropriate for the test file. Using
node:fswould be more consistent with the implementation file, but this is a minor nit.
11-21: LGTM!Good test hygiene with proper setup/teardown using temporary directories. The
fs.rmSyncwithrecursive: true, force: trueensures clean teardown even if tests fail.
24-44: LGTM!Well-structured test for basic local module loading via
./path. The test correctly validates that the custom require function resolves and loads local modules.
46-72: LGTM!Good test for nested module resolution with
../paths. This validates the parent directory traversal and nested require chains work correctly.
74-96: LGTM!Important cross-platform test for Windows-style backslash handling. The double-escaped backslashes in the script string are correct for testing backslash normalization.
98-108: LGTM!Critical security test ensuring access outside allowed context roots is properly blocked. The error message assertion matches the implementation.
111-139: LGTM!This test addresses the previous review concern. The test now correctly uses
../shared/sharedto traverse from collection to testDir then into the shared directory, which is properly allowed viaadditionalContextRoots.
141-167: LGTM!Good test validating that relative paths in
additionalContextRootsare resolved correctly againstcollectionPath.
169-205: LGTM!Important test for nested module chains accessing additional context roots. This validates that the
additionalContextRootsAbsoluteis correctly propagated through nestedcreateCustomRequirecalls.
208-224: LGTM!Good coverage for npm module loading. Using
lodash(already a project dependency) is pragmatic.packages/bruno-js/src/sandbox/node-vm/index.js (6)
41-48: LGTM!Clean computation of absolute context roots. The lodash chain normalizes relative paths against
collectionPathand always includescollectionPathitself. This ensures consistent root handling.
85-93: LGTM!The pre-computed
additionalContextRootsAbsoluteis now passed directly tocreateCustomRequire, addressing the previous review concern about recomputation.
123-138: LGTM!Good cross-platform handling. Normalizing backslashes to forward slashes before the local module check ensures Windows paths work correctly. The
additionalContextRootsAbsoluteparameter is properly passed through.
192-220: LGTM!The security check correctly validates that the resolved file path is within at least one of the allowed roots. Using
path.relativeand checking for..prefix is a robust approach. The error message is informative, listing all allowed roots.
248-256: Previous review concern addressed.The nested
createCustomRequirenow receivesadditionalContextRootsAbsolutedirectly as a parameter instead of recomputing it fromscriptContext.scriptingConfig. This ensures consistent allowed roots across nested module loads.Note: Line 254 still reads
allowScriptFilesystemAccessfromscriptContext.scriptingConfig, which is slightly inconsistent with passingadditionalContextRootsAbsolutedirectly. However, this is acceptable sincefilesystemAccess.allowis a simple boolean that doesn't require the same normalization logic.
159-159: Module resolution priority is intentional for sandboxed context.The path order
[...additionalContextRootsAbsolute, ...module.paths]at line 159 is deliberate design for Bruno's sandboxed scripting environment. The collection path and additional context roots are explicitly prioritized to support isolated script execution within collections. This behavior is tested, documented in error messages, and aligns with the sandboxed VM context (line 80:vm.runInNewContext). Local module shadowing of npm packages is expected and supports collection-scoped dependencies.Likely an incorrect or invalid review comment.
Description
Contribution Checklist:
Note: Keeping the PR small and focused helps make it easier to review and merge. If you have multiple changes you want to make, please consider submitting them as separate pull requests.
Publishing to New Package Managers
Please see here for more information.
Summary by CodeRabbit
New Features
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.