Skip to content

Commit

Permalink
esm: protect ERR_UNSUPPORTED_DIR_IMPORT against prototype pollution
Browse files Browse the repository at this point in the history
PR-URL: #49060
Backport-PR-URL: #50669
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
  • Loading branch information
aduh95 authored and targos committed Nov 23, 2023
1 parent d5a1153 commit 385f24c
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 25 deletions.
7 changes: 5 additions & 2 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1692,8 +1692,11 @@ E('ERR_UNKNOWN_FILE_EXTENSION', (ext, path, suggestion) => {
E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s for URL %s',
RangeError);
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError);
E('ERR_UNSUPPORTED_DIR_IMPORT', "Directory import '%s' is not supported " +
'resolving ES modules imported from %s', Error);
E('ERR_UNSUPPORTED_DIR_IMPORT', function(path, base, exactUrl) {
lazyInternalUtil().setOwnProperty(this, 'url', exactUrl);
return `Directory import '${path}' is not supported ` +
`resolving ES modules imported from ${base}`;
}, Error);
E('ERR_UNSUPPORTED_ESM_URL_SCHEME', (url, supported) => {
let msg = `Only URLs with a scheme in: ${formatList(supported)} are supported by the default ESM loader`;
if (isWindows && url.protocol.length === 2) {
Expand Down
4 changes: 1 addition & 3 deletions lib/internal/modules/esm/resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,7 @@ function finalizeResolution(resolved, base, preserveSymlinks) {

// Check for stats.isDirectory()
if (stats === 1) {
const err = new ERR_UNSUPPORTED_DIR_IMPORT(path, fileURLToPath(base));
err.url = String(resolved);
throw err;
throw new ERR_UNSUPPORTED_DIR_IMPORT(path, fileURLToPath(base), String(resolved));
} else if (stats !== 0) {
// Check for !stats.isFile()
if (process.env.WATCH_REPORT_DEPENDENCIES && process.send) {
Expand Down
38 changes: 18 additions & 20 deletions test/es-module/test-esm-main-lookup.mjs
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
import '../common/index.mjs';
import { mustNotCall } from '../common/index.mjs';
import * as fixtures from '../common/fixtures.mjs';
import assert from 'assert';

async function main() {
let mod;
try {
mod = await import('../fixtures/es-modules/pjson-main');
} catch (e) {
assert.strictEqual(e.code, 'ERR_UNSUPPORTED_DIR_IMPORT');
}
Object.defineProperty(Error.prototype, 'url', {
get: mustNotCall('get %Error.prototype%.url'),
set: mustNotCall('set %Error.prototype%.url'),
});
Object.defineProperty(Object.prototype, 'url', {
get: mustNotCall('get %Object.prototype%.url'),
set: mustNotCall('set %Object.prototype%.url'),
});

assert.strictEqual(mod, undefined);
await assert.rejects(import('../fixtures/es-modules/pjson-main'), {
code: 'ERR_UNSUPPORTED_DIR_IMPORT',
url: fixtures.fileURL('es-modules/pjson-main').href,
});

try {
mod = await import('../fixtures/es-modules/pjson-main/main.mjs');
} catch (e) {
console.log(e);
assert.fail();
}

assert.strictEqual(mod.main, 'main');
}

main();
assert.deepStrictEqual(
{ ...await import('../fixtures/es-modules/pjson-main/main.mjs') },
{ main: 'main' },
);

0 comments on commit 385f24c

Please sign in to comment.