X Tutup
The Wayback Machine - https://web.archive.org/web/20230103070948/https://github.com/nodejs/node/pull/46065
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: make Error objects instantiation less vulnerable to prototype pollution #46065

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

aduh95
Copy link
Contributor

@aduh95 aduh95 commented Jan 2, 2023

Having a more robust Error instantiation makes sure the user would get the actual error rather than an unrelated one if the prototype was altered somewhere else.

Before this change:

$ node -e 'Object.defineProperty(Object.prototype, "code", {set(){throw new Error}});fs.readFile()'              
[eval]:1
Object.defineProperty(Object.prototype, "code", {set(){throw new Error}});fs.readFile()
                                                       ^

Error
    at TypeError.set ([eval]:1:62)
    at new NodeError (node:internal/errors:401:16)
    at __node_internal_ (node:internal/validators:421:11)
    at maybeCallback (node:fs:169:3)
    at Object.readFile (node:fs:372:14)
    at [eval]:1:78
    at Script.runInThisContext (node:vm:129:12)
    at Object.runInThisContext (node:vm:307:38)
    at node:internal/process/execution:83:21
    at [eval]-wrapper:6:24

Node.js v19.3.0

After this change:

$ node -e 'Object.defineProperty(Object.prototype, "code", {set(){throw new Error}});fs.readFile()'
node:internal/validators:421
    throw new ERR_INVALID_ARG_TYPE(name, 'Function', value);
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The "cb" argument must be of type function. Received undefined
    at maybeCallback (node:fs:169:3)
    at Object.readFile (node:fs:372:14)
    at [eval]:1:78
    at Script.runInThisContext (node:vm:128:12)
    at Object.runInThisContext (node:vm:306:38)
    at node:internal/process/execution:83:21
    at [eval]-wrapper:6:24
    at runScript (node:internal/process/execution:82:62)
    at evalScript (node:internal/process/execution:104:10)
    at node:internal/main/eval_string:50:3 {
  code: 'ERR_INVALID_ARG_TYPE'
}

Node.js v20.0.0-pre

@aduh95 aduh95 added errors Issues and PRs related to JavaScript errors originated in Node.js core. needs-benchmark-ci PR that need a benchmark CI run. labels Jan 2, 2023
@nodejs-github-bot
Copy link
Contributor

nodejs-github-bot commented Jan 2, 2023

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Jan 2, 2023
const kIsNodeError = Symbol('kIsNodeError');

const isWindows = process.platform === 'win32';

const messages = new SafeMap();
const codes = {};
const codes = ObjectCreate(null);
Copy link
Member

@ljharb ljharb Jan 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const codes = ObjectCreate(null);
const codes = { __proto__: null };

this is equally robust and avoids a function call.

Copy link
Contributor

@JakobJingleheimer JakobJingleheimer Jan 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do prefer this, but I know Antoine prefers the other, and the diff is pretty "6 of one".

Copy link
Member

@ljharb ljharb Jan 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the preference?

Even setting aside that Object.create is a regretted addition to the JS language, it's still got the potential overhead of a function call, as compared to the very straightforward syntax that node already uses with objects initialized with more than one property. Why is "no properties" a special case that requires a function call?

* @returns {T}
*/
function assignOwnProperties(obj, ...sources) {
const descriptors = ObjectCreate(null);
Copy link
Member

@ljharb ljharb Jan 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const descriptors = ObjectCreate(null);
const descriptors = { __proto__: null };

lib/internal/util/safe-property-assignment.js Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
errors Issues and PRs related to JavaScript errors originated in Node.js core. lib / src Issues and PRs related to general changes in the lib or src directory. needs-benchmark-ci PR that need a benchmark CI run. needs-ci PRs that need a full CI run.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants
X Tutup