mirror of
https://github.com/openai/codex.git
synced 2026-05-04 03:16:31 +00:00
js_repl: canonicalize paths for node_modules boundary checks (#12177)
## Summary Fix `js_repl` package-resolution boundary checks for macOS temp directory path aliasing (`/var` vs `/private/var`). ## Problem `js_repl` verifies that resolved bare-package imports stay inside a configured `node_modules` root. On macOS, temp directories are commonly exposed as `/var/...` but canonicalize to `/private/var/...`. Because the boundary check compared raw paths with `path.relative(...)`, valid resolutions under temp dirs could be misclassified as escaping the allowed base, causing false `Module not found` errors. ## Changes - Add `fs` import in the JS kernel. - Add `canonicalizePath()` using `fs.realpathSync.native(...)` (with safe fallback). - Canonicalize both `base` and `resolvedPath` before running the `node_modules` containment check. ## Impact - Fixes false-negative boundary checks for valid package resolutions in macOS temp-dir scenarios. - Keeps the existing security boundary behavior intact. - Scope is limited to `js_repl` kernel module path validation logic. #### [git stack](https://github.com/magus/git-stack-cli) - 👉 `1` https://github.com/openai/codex/pull/12177 - ⏳ `2` https://github.com/openai/codex/pull/10673
This commit is contained in:
committed by
GitHub
parent
82d82d9ca5
commit
cc248e4681
@@ -4,6 +4,7 @@
|
||||
|
||||
const { Buffer } = require("node:buffer");
|
||||
const crypto = require("node:crypto");
|
||||
const fs = require("node:fs");
|
||||
const { builtinModules, createRequire } = require("node:module");
|
||||
const { createInterface } = require("node:readline");
|
||||
const { performance } = require("node:perf_hooks");
|
||||
@@ -149,6 +150,14 @@ const moduleSearchBases = (() => {
|
||||
const importResolveConditions = new Set(["node", "import"]);
|
||||
const requireByBase = new Map();
|
||||
|
||||
function canonicalizePath(value) {
|
||||
try {
|
||||
return fs.realpathSync.native(value);
|
||||
} catch {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
function getRequireForBase(base) {
|
||||
let req = requireByBase.get(base);
|
||||
if (!req) {
|
||||
@@ -165,8 +174,10 @@ function isModuleNotFoundError(err) {
|
||||
}
|
||||
|
||||
function isWithinBaseNodeModules(base, resolvedPath) {
|
||||
const nodeModulesRoot = path.resolve(base, "node_modules");
|
||||
const relative = path.relative(nodeModulesRoot, resolvedPath);
|
||||
const canonicalBase = canonicalizePath(base);
|
||||
const canonicalResolved = canonicalizePath(resolvedPath);
|
||||
const nodeModulesRoot = path.resolve(canonicalBase, "node_modules");
|
||||
const relative = path.relative(nodeModulesRoot, canonicalResolved);
|
||||
return (
|
||||
relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user