ITADN

[Detail Bug] Sandbox: Dependency whitelist in vmOpts.allow is ignored, allowing imports of any package

#690Closeddetail-app[bot] 创建于 2026-03-02
D
detail-app[bot]commented
# Detail Bug Report https://app.detail.dev/org_06887db3-bf54-40ab-976d-46c66ab2b840/bugs/bug_7d906711-8afc-44f8-b572-01046edcaed1 # Summary - **Context**: The `function.js` module executes user code in an isolated sandbox by calling `isolated-function` with security options including permissions and dependency whitelists. - **Bug**: The code unconditionally overrides the entire `allow` object when passing options to `isolated-function`, discarding any `allow.dependencies` or `allow.permissions` that were provided in `vmOpts`. - **Actual vs. expected**: When `vmOpts.allow.dependencies` is provided to restrict which npm packages can be imported, this security restriction is silently ignored. Expected behavior is to merge the permissions while preserving the dependencies whitelist. - **Impact**: This allows untrusted code to import and execute any npm package, bypassing dependency whitelisting intended for security. # Code with Bug In `packages/function/src/function.js`: ```javascript module.exports = async ({ url, code, vmOpts, browserWSEndpoint, needsNetwork = template.isUsingPage(code), source = template(code, needsNetwork), ...opts }) => { const permissions = needsNetwork && nodeMajor >= 25 ? ['net'] : [] const [fn, teardown] = isolatedFunction(source, { ...vmOpts, allow: { permissions }, // <-- BUG 🔴 Completely replaces vmOpts.allow, discarding vmOpts.allow.dependencies throwError: false }) const result = await fn(url, browserWSEndpoint, opts) await teardown() return result } ``` # Explanation Because `...vmOpts` is applied first and then `allow: { permissions }` is set afterward, any `vmOpts.allow` object is overwritten. As a result: - `vmOpts.allow.dependencies` is dropped, so dependency whitelisting is not enforced. - `vmOpts.allow.permissions` is also replaced, causing unexpected permission behavior. Evidence: a repro passing `vmOpts.allow.dependencies: ['lodash']` while user code does `require('fs')` succeeds (returns `{ isFulfilled: true, value: 'success' }`) instead of failing with a dependency-not-allowed error. # Exploit Scenario An attacker (or any untrusted user code executed by this sandbox) can bypass an intended `vmOpts.allow.dependencies` whitelist and import arbitrary modules/packages (e.g., `fs` or other installed npm packages), even when the caller believes imports are restricted. # Recommended Fix Merge `allow` rather than replacing it, preserving `vmOpts.allow.dependencies` and combining permissions: ```javascript const vmOptsAllow = vmOpts?.allow || {} const [fn, teardown] = isolatedFunction(source, { ...vmOpts, allow: { ...vmOptsAllow, permissions: [ ...(vmOptsAllow.permissions || []), ...permissions ] }, throwError: false }) ``` # History This bug was introduced in commit a1361409. The commit upgraded the `isolated-function` dependency from v0.1.46 to v0.1.47 (changing `allow` from an array to an object), and updated the call site to `allow: { permissions }` without merging with `vmOpts.allow`, discarding `allow.dependencies`.
关闭于 2026-05-17 0 条评论