From 4f75474c8741d4073d91af36cbb7c77002f319ca Mon Sep 17 00:00:00 2001 From: naman-bruno Date: Mon, 19 Jan 2026 19:33:00 +0530 Subject: [PATCH] remove allowScriptFilesystemAccess flag (#6834) --- .../collection-json-from-pathname.spec.js | 1 - .../collection/bruno.json | 5 +- .../bruno-js/src/sandbox/node-vm/index.js | 37 +------- packages/bruno-tests/collection/bruno.json | 5 +- .../collection_level_oauth2/bruno.json | 5 +- .../bruno-tests/collection_oauth2/bruno.json | 5 +- .../bruno-missing-required-fields.json | 5 +- .../bruno/fixtures/bruno-testbench.json | 5 +- .../collections/should_allow_fs/bruno.json | 7 +- .../collections/should_disallow_fs/bruno.json | 14 --- .../should_disallow_fs/request.bru | 15 ---- .../scripting/inbuilt-libraries/fs/fs.spec.ts | 88 +++++-------------- .../fs/init-user-data/preferences.json | 3 +- 13 files changed, 33 insertions(+), 162 deletions(-) delete mode 100644 tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_disallow_fs/bruno.json delete mode 100644 tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_disallow_fs/request.bru diff --git a/packages/bruno-cli/tests/runner/collection-json-from-pathname.spec.js b/packages/bruno-cli/tests/runner/collection-json-from-pathname.spec.js index 2be4d9e66..d0025cbf6 100644 --- a/packages/bruno-cli/tests/runner/collection-json-from-pathname.spec.js +++ b/packages/bruno-cli/tests/runner/collection-json-from-pathname.spec.js @@ -36,7 +36,6 @@ describe('create collection json from pathname', () => { expect(c).toHaveProperty('brunoConfig.proxy.auth.password', ''); expect(c).toHaveProperty('brunoConfig.proxy.bypassProxy', ''); expect(c).toHaveProperty('brunoConfig.scripts.moduleWhitelist', ['crypto', 'buffer']); - expect(c).toHaveProperty('brunoConfig.scripts.filesystemAccess.allow', true); expect(c).toHaveProperty('brunoConfig.clientCertificates.enabled', true); expect(c).toHaveProperty('brunoConfig.clientCertificates.certs', []); diff --git a/packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/bruno.json b/packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/bruno.json index 366f84472..516572e5e 100644 --- a/packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/bruno.json +++ b/packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/bruno.json @@ -19,10 +19,7 @@ "bypassProxy": "" }, "scripts": { - "moduleWhitelist": ["crypto", "buffer"], - "filesystemAccess": { - "allow": true - } + "moduleWhitelist": ["crypto", "buffer"] }, "clientCertificates": { "enabled": true, diff --git a/packages/bruno-js/src/sandbox/node-vm/index.js b/packages/bruno-js/src/sandbox/node-vm/index.js index efb5e60a2..1646623e3 100644 --- a/packages/bruno-js/src/sandbox/node-vm/index.js +++ b/packages/bruno-js/src/sandbox/node-vm/index.js @@ -36,8 +36,6 @@ async function runScriptInNodeVm({ } try { - const allowScriptFilesystemAccess = get(scriptingConfig, 'filesystemAccess.allow', false); - // Compute additional context roots const additionalContextRoots = get(scriptingConfig, 'additionalContextRoots', []); const additionalContextRootsAbsolute = lodash @@ -88,7 +86,6 @@ async function runScriptInNodeVm({ scriptContext, currentModuleDir: collectionPath, localModuleCache, - allowScriptFilesystemAccess, additionalContextRootsAbsolute }); @@ -116,7 +113,6 @@ async function runScriptInNodeVm({ * @param {Object} options.scriptContext - Script execution context * @param {string} options.currentModuleDir - Current module directory for relative imports * @param {Map} options.localModuleCache - Cache for loaded local modules - * @param {boolean} options.allowScriptFilesystemAccess - Whether to allow fs module access * @param {Array} options.additionalContextRootsAbsolute - Pre-computed absolute context roots * @returns {Function} Custom require function */ @@ -126,7 +122,6 @@ function createCustomRequire({ scriptContext, currentModuleDir = collectionPath, localModuleCache = new Map(), - allowScriptFilesystemAccess = false, additionalContextRootsAbsolute = [] }) { return (moduleName) => { @@ -137,40 +132,11 @@ function createCustomRequire({ return loadLocalModule({ moduleName: normalizedModuleName, collectionPath, scriptContext, localModuleCache, currentModuleDir, additionalContextRootsAbsolute }); } - // Helper function to check if a module is the fs module or a submodule - const isFsModule = (module) => { - if (!module) return false; - const fsModule = require('fs'); - // Check if it's the fs module itself - if (module === fsModule) return true; - // Check if it's fs/promises submodule - if (module === fsModule.promises) return true; - // Check if it's fs/promises by comparing with require('fs/promises') - try { - if (module === require('fs/promises')) return true; - } catch { - // fs/promises might not be available in all Node versions - } - return false; - }; - // First try to require as a native/npm module try { const requiredModulePath = require.resolve(moduleName, { paths: [...additionalContextRootsAbsolute, ...module.paths] }); - const requiredModule = require(requiredModulePath); - - // Block filesystem module access if filesystem access is not allowed - if (!allowScriptFilesystemAccess && isFsModule(requiredModule)) { - throw new Error('Filesystem access is not allowed. Enable "filesystemAccess.allow" in scripting config to use the fs module.'); - } - - return requiredModule; + return require(requiredModulePath); } catch (requireError) { - // Re-throw if it's our filesystem access error - if (requireError.message && requireError.message.includes('Enable "filesystemAccess.allow"')) { - throw requireError; - } - // If that fails, try to resolve from additionalContextRoots 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'}`); } @@ -251,7 +217,6 @@ function loadLocalModule({ scriptContext, currentModuleDir: moduleDir, localModuleCache, - allowScriptFilesystemAccess: get(scriptContext.scriptingConfig, 'filesystemAccess.allow', false), additionalContextRootsAbsolute }) }; diff --git a/packages/bruno-tests/collection/bruno.json b/packages/bruno-tests/collection/bruno.json index d2aa0a97a..bf402caf3 100644 --- a/packages/bruno-tests/collection/bruno.json +++ b/packages/bruno-tests/collection/bruno.json @@ -15,10 +15,7 @@ "bypassProxy": "" }, "scripts": { - "moduleWhitelist": ["crypto", "buffer", "form-data"], - "filesystemAccess": { - "allow": true - } + "moduleWhitelist": ["crypto", "buffer", "form-data"] }, "clientCertificates": { "enabled": true, diff --git a/packages/bruno-tests/collection_level_oauth2/bruno.json b/packages/bruno-tests/collection_level_oauth2/bruno.json index 17f1d8ea0..4771de446 100644 --- a/packages/bruno-tests/collection_level_oauth2/bruno.json +++ b/packages/bruno-tests/collection_level_oauth2/bruno.json @@ -3,10 +3,7 @@ "name": "collection_level_oauth2", "type": "collection", "scripts": { - "moduleWhitelist": ["crypto"], - "filesystemAccess": { - "allow": true - } + "moduleWhitelist": ["crypto"] }, "clientCertificates": { "enabled": true, diff --git a/packages/bruno-tests/collection_oauth2/bruno.json b/packages/bruno-tests/collection_oauth2/bruno.json index 82816b2b5..5b3b41c84 100644 --- a/packages/bruno-tests/collection_oauth2/bruno.json +++ b/packages/bruno-tests/collection_oauth2/bruno.json @@ -5,10 +5,7 @@ "scripts": { "moduleWhitelist": [ "crypto" - ], - "filesystemAccess": { - "allow": true - } + ] }, "clientCertificates": { "enabled": true, diff --git a/tests/import/bruno/fixtures/bruno-missing-required-fields.json b/tests/import/bruno/fixtures/bruno-missing-required-fields.json index 6ecf37a09..07735d8ff 100644 --- a/tests/import/bruno/fixtures/bruno-missing-required-fields.json +++ b/tests/import/bruno/fixtures/bruno-missing-required-fields.json @@ -2916,10 +2916,7 @@ "crypto", "buffer", "form-data" - ], - "filesystemAccess": { - "allow": true - } + ] }, "clientCertificates": { "enabled": true, diff --git a/tests/import/bruno/fixtures/bruno-testbench.json b/tests/import/bruno/fixtures/bruno-testbench.json index 02a9c29fb..86bc74a18 100644 --- a/tests/import/bruno/fixtures/bruno-testbench.json +++ b/tests/import/bruno/fixtures/bruno-testbench.json @@ -2917,10 +2917,7 @@ "crypto", "buffer", "form-data" - ], - "filesystemAccess": { - "allow": true - } + ] }, "clientCertificates": { "enabled": true, diff --git a/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_allow_fs/bruno.json b/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_allow_fs/bruno.json index 6130abc78..9cffa1274 100644 --- a/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_allow_fs/bruno.json +++ b/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_allow_fs/bruno.json @@ -5,10 +5,5 @@ "ignore": [ "node_modules", ".git" - ], - "scripts": { - "filesystemAccess": { - "allow": true - } - } + ] } \ No newline at end of file diff --git a/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_disallow_fs/bruno.json b/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_disallow_fs/bruno.json deleted file mode 100644 index e751a8433..000000000 --- a/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_disallow_fs/bruno.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": "1", - "name": "should_disallow_fs", - "type": "collection", - "ignore": [ - "node_modules", - ".git" - ], - "scripts": { - "filesystemAccess": { - "allow": false - } - } -} \ No newline at end of file diff --git a/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_disallow_fs/request.bru b/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_disallow_fs/request.bru deleted file mode 100644 index 2a2fd846a..000000000 --- a/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_disallow_fs/request.bru +++ /dev/null @@ -1,15 +0,0 @@ -meta { - name: request - type: http - seq: 1 -} - -post { - url: https://echo.usebruno.com - body: none - auth: none -} - -script:pre-request { - const fs = require('fs'); -} \ No newline at end of file diff --git a/tests/scripting/inbuilt-libraries/fs/fs.spec.ts b/tests/scripting/inbuilt-libraries/fs/fs.spec.ts index 72471fbb7..567107af9 100644 --- a/tests/scripting/inbuilt-libraries/fs/fs.spec.ts +++ b/tests/scripting/inbuilt-libraries/fs/fs.spec.ts @@ -2,79 +2,39 @@ import { test } from '../../../../playwright'; import { setSandboxMode, runCollection, validateRunnerResults } from '../../../utils/page'; test.describe.serial('`fs` library', () => { - test.describe('should allow `fs` library', () => { - test('developer mode', async ({ pageWithUserData: page }) => { - test.setTimeout(2 * 60 * 1000); + test('developer mode allows fs', async ({ pageWithUserData: page }) => { + test.setTimeout(2 * 60 * 1000); - // Set up developer mode - await setSandboxMode(page, 'should_allow_fs', 'developer'); + // Set up developer mode + await setSandboxMode(page, 'should_allow_fs', 'developer'); - // Run the collection - await runCollection(page, 'should_allow_fs'); + // Run the collection + await runCollection(page, 'should_allow_fs'); - // Validate test results - await validateRunnerResults(page, { - totalRequests: 1, - passed: 1, - failed: 0, - skipped: 0 - }); - }); - - test('safe mode', async ({ pageWithUserData: page }) => { - test.setTimeout(2 * 60 * 1000); - - // Set up safe mode - await setSandboxMode(page, 'should_allow_fs', 'safe'); - - // Run the collection - await runCollection(page, 'should_allow_fs'); - - // Validate test results - await validateRunnerResults(page, { - totalRequests: 1, - passed: 0, - failed: 1, - skipped: 0 - }); + // Validate test results + await validateRunnerResults(page, { + totalRequests: 1, + passed: 1, + failed: 0, + skipped: 0 }); }); - test.describe('should disallow `fs` library', () => { - test('developer mode', async ({ pageWithUserData: page }) => { - test.setTimeout(2 * 60 * 1000); + test('safe mode blocks fs', async ({ pageWithUserData: page }) => { + test.setTimeout(2 * 60 * 1000); - // Set up developer mode - await setSandboxMode(page, 'should_disallow_fs', 'developer'); + // Set up safe mode + await setSandboxMode(page, 'should_allow_fs', 'safe'); - // Run the collection - await runCollection(page, 'should_disallow_fs'); + // Run the collection + await runCollection(page, 'should_allow_fs'); - // Validate test results - await validateRunnerResults(page, { - totalRequests: 1, - passed: 0, - failed: 1, - skipped: 0 - }); - }); - - test('safe mode', async ({ pageWithUserData: page }) => { - test.setTimeout(2 * 60 * 1000); - - // Set up safe mode - await setSandboxMode(page, 'should_disallow_fs', 'safe'); - - // Run the collection - await runCollection(page, 'should_disallow_fs'); - - // Validate test results - await validateRunnerResults(page, { - totalRequests: 1, - passed: 0, - failed: 1, - skipped: 0 - }); + // Validate test results + await validateRunnerResults(page, { + totalRequests: 1, + passed: 0, + failed: 1, + skipped: 0 }); }); }); diff --git a/tests/scripting/inbuilt-libraries/fs/init-user-data/preferences.json b/tests/scripting/inbuilt-libraries/fs/init-user-data/preferences.json index f0272aaa3..acc5b8721 100644 --- a/tests/scripting/inbuilt-libraries/fs/init-user-data/preferences.json +++ b/tests/scripting/inbuilt-libraries/fs/init-user-data/preferences.json @@ -1,7 +1,6 @@ { "maximized": false, "lastOpenedCollections": [ - "{{projectRoot}}/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_allow_fs", - "{{projectRoot}}/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_disallow_fs" + "{{projectRoot}}/tests/scripting/inbuilt-libraries/fs/fixtures/collections/should_allow_fs" ] } \ No newline at end of file