GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — tools: add eslint rule for `__proto__: null` in object by rluvaton · Pull Request #48646 · nodejs/node

Conversation

@rluvaton

@rluvaton rluvaton commented Jul 3, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

instead of each review someone need to remind that you need to add __proto__: null when creating an object, I created this eslint rule

before continue let's agree on the name so I won't need to rename after adding ignore comments

this does not add __proto__: null to module.exports as it break the ecosystem.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@rluvaton
tools: add eslint rule for __proto__ null in object
f45c225
@nodejs-github-bot nodejs-github-bot added the tools Issues and PRs related to the tools directory. label Jul 3, 2023
@rluvaton rluvaton mentioned this pull request Jul 3, 2023
test_runner: add shards support #48639
Merged
5 tasks done
rluvaton added 2 commits July 3, 2023 19:47
@rluvaton
tools: made it fixable
361734b
@rluvaton
tools: made it fixable
a721c26
cjihrig
cjihrig reviewed Jul 3, 2023
View reviewed changes

@cjihrig cjihrig left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

should it only run for the lib folder?

Yes, I think so.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread tools/eslint-rules/set-proto-to-null-in-object.js Outdated
let hasProto = false;

for (const property of properties) {
if (property.key && property.key.name === '__proto__') {

@cjihrig cjihrig Jul 3, 2023

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Can we verify that the value is null?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@rluvaton rluvaton Jul 3, 2023

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

yes, and I'm gonna make it fixable

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@rluvaton rluvaton Jul 3, 2023

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

there are cases where we want to have __proto__ to not be null, see https://github.com/nodejs/node/blob/757c10414776b6f035ced453599527a841f47d6e/tools/eslint-rules/prefer-proto.js

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

aduh95 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
rluvaton added 4 commits July 3, 2023 20:04
@rluvaton
run only for lib files
94ab2e1
@rluvaton
fix eslint rule to not support literal proto property
bb69b0f
@rluvaton
ignore adding proto for the module exports
ab4e640
@rluvaton
do not add __proto__: null to module.exports
94e8626
@rluvaton

rluvaton commented Jul 3, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

Could you please run the CITGM, I'm 90% sure it can break the ecosystem after adding to all the codebase

after that if there are a lot of conflicts I will revert the added proto to the code base and rerun it...

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rluvaton
rluvaton marked this pull request as ready for review July 3, 2023 17:52
ljharb
ljharb reviewed Jul 3, 2023
View reviewed changes

@ljharb ljharb left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

it'd be awesome if the autofix could handle the multiline piece properly too

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

aduh95 and JakobJingleheimer reacted with thumbs up emoji
All reactions
  • 👍 2 reactions
Comment thread lib/_http_outgoing.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/_http_incoming.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

@rluvaton

rluvaton commented Jul 3, 2023

Copy link
Copy Markdown
Member Author

it'd be awesome if the autofix could handle the multiline piece properly too

@ljharb agree but before I fix this I want to run the CITGM as I'm afraid it gonna break the eco, can you please run it for me?

ljharb and Kifzy reacted with thumbs up emoji
All reactions
  • 👍 2 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ljharb

ljharb commented Jul 3, 2023

Copy link
Copy Markdown
Member

I'm not able to, unfortunately.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

aduh95
aduh95 reviewed Jul 3, 2023
View reviewed changes
Comment thread lib/_http_client.js
Comment on lines 329 to 333
let optsWithoutSignal = options;
if (optsWithoutSignal.signal) {
optsWithoutSignal = ObjectAssign({}, options);
optsWithoutSignal = ObjectAssign({ __proto__: null }, options);
delete optsWithoutSignal.signal;
}

@aduh95 aduh95 Jul 3, 2023

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Suggested change
let optsWithoutSignal = options;
if (optsWithoutSignal.signal) {
optsWithoutSignal = ObjectAssign({}, options);
optsWithoutSignal = ObjectAssign({ __proto__: null }, options);
delete optsWithoutSignal.signal;
}
const { signal, ...optsWithoutSignal } = options;

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ljharb reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@rluvaton rluvaton Jul 4, 2023

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I want to avoid code changes that are not related to this 😄

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@aduh95

aduh95 commented Jul 3, 2023

Copy link
Copy Markdown
Contributor

You would need to split this PR in chunks small enough to be reviewable, I think the diff is too big to be reviewed in one go, and you are going to run in an endless stream of conflicts.

JakobJingleheimer and MoLow reacted with thumbs up emoji
All reactions
  • 👍 2 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Trott
Trott reviewed Jul 3, 2023
View reviewed changes
Comment thread lib/zlib.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

@Trott

Trott commented Jul 3, 2023

Copy link
Copy Markdown
Member

You would need to split this PR in chunks small enough to be reviewable, I think the diff is too big to be reviewed in one go, and you are going to run in an endless stream of conflicts.

Yeah, I hate to say it, but this is going to have to be done in smaller pieces. Here's one option:

  1. Convert this PR to draft mode.
  2. Open a few PRs to make the changes that are in this PR but in only a single file (e.g., lib/assert.js) or a coherent set of files (e.g., lib/_http*). So, maybe one PR for lib/assert.js and one for lib/_http* and one for lib/zlib.js. Or whatever ones you want. But small PRs that can be reviewed.
  3. They'll all be semver-major and need to go through CITGM, but on the upside, if a change in one PR breaks something in the ecosystem, at least it won't hold up the other changes.
  4. Point people to this PR when they invariably comment that there must be a lint rule.
  5. Keep rebasing this PR to get rid of conflicts. If that proves to be too much of a pain, close this and open a draft PR with just the lint rule stuff. Keep that one rebased. Eventually, GitHub Actions will show no more things to be fixed and it can be set as Ready For Review.

There are other valid approaches too. But an all-at-once approach like this is unlikely to get reviewed much, I'm sorry to say.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Trott

Trott commented Jul 3, 2023

Copy link
Copy Markdown
Member

(Also: Thank you for doing this and wanting to make the Node.js runtime more secure!)

MoLow reacted with thumbs up emoji rluvaton reacted with hooray emoji
All reactions
  • 👍 1 reaction
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ljharb

ljharb commented Jul 3, 2023

Copy link
Copy Markdown
Member

Would they be semver-major if the object isn't being passed out to user code?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@benjamingr

benjamingr commented Jul 3, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

CIGTM run: https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/3177/ (it did not start yet but I queued it)

rluvaton reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@aduh95

aduh95 commented Jul 3, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

CIGTM run: https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/3177/ (it did not start yet but I queued it)

It's unlikely to give us much insight, we are not going to land this PR in this state anyway, no matter the result of this run we will still want it split up in several PRs, and each PR will probably need a CITGM run 🤷‍♂️

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rluvaton

rluvaton commented Jul 3, 2023

Copy link
Copy Markdown
Member Author

Before I continue with this I wanna know what I'm dealing with...

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@aduh95

aduh95 commented Jul 3, 2023

Copy link
Copy Markdown
Contributor

I cancelled the run so it doesn't go in the way of the pending release (scheduled for tomorrow).

Before I continue with this I wanna know what I'm dealing with...

Well I'm afraid you are not going to get anything useful out of it; if the results show lots of regressions, that doesn't mean that we won't introduce the lint rule, just that we need to investigate where they are coming from, and that's going to be much easier on smaller PRs. Even if a CITGM show no regressions on this PR, I would argue this is a waste of time and resources because we probably want to run it again on the PRs that are actually going to land.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rluvaton

rluvaton commented Jul 3, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

@Trott what if we gonna:

  1. merge this PR with only the lint rule set as warning without the auto fix
  2. Cover the entire code base through number of small PRs
  3. Turn on the auto fix and set it to error

This way I won't need to keep rebasing, and I could work on this without much of a conflict

(Not sure if should have autofix enabled as it's can be dangerous)

WDYT?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rluvaton

rluvaton commented Jul 3, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

Before I go through this journey, where should we NOT add the __proto__: null? When returning objects to userland? If so, there are a lot of those and the lint rule would just make a lot of noise when disabling for each one of them

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Trott

Trott commented Jul 3, 2023

Copy link
Copy Markdown
Member
  1. merge this PR with only the lint rule set as warning without the auto fix

Our lint jobs treat warnings as errors. Changing that is not impossible but others might oppose the change.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@benjamingr

benjamingr commented Jul 4, 2023

Copy link
Copy Markdown
Member

I don't understand why not run CITGM, it will show a lot of regressions, @rluvaton can then go ahead and compare them to the release CITGM and then get an effort estimation of how much extra breakage there is for the whole thing.

It's entirely reasonable from his PoV to want to know roughly how much work there is here and whether he wants to invest time into this. I don't understand the reluctance to run CITGM here? (if it's just the release can you start one after the release?)

rluvaton reacted with laugh emoji
All reactions
  • 😄 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@joyeecheung

joyeecheung commented Jul 4, 2023

Copy link
Copy Markdown
Member

Before I go through this journey, where should we NOT add the proto: null?

I think in general this is only needed when we are accessing properties that may not have been defined in the object e.g. checking if it's undefined or falsy, when the object can come from user land or from internal code that does not define these properties. For completely internal objects where the creators always define the keys, a null prototype puts the object in dictionary mode and the lookup would be slower than it could've been. https://v8.dev/blog/fast-properties

rluvaton reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

rluvaton added 2 commits July 5, 2023 00:03
@rluvaton
fix eslint rule to add multiline when needed
843c110
@rluvaton
fix eslint rule for single property object
68b033b
@rluvaton
rluvaton force-pushed the add-proto-null-in-object-eslint-rule branch from 1a91514 to 68b033b Compare July 4, 2023 21:09
@rluvaton
Merge branch 'main' into add-proto-null-in-object-eslint-rule
aafd615
@rluvaton
rluvaton force-pushed the add-proto-null-in-object-eslint-rule branch from a5f145c to aafd615 Compare July 4, 2023 21:18
@rluvaton
fix multiline
8726909
@rluvaton

rluvaton commented Jul 5, 2023

Copy link
Copy Markdown
Member Author

Can we run the CITGM after the release, please?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

rluvaton added 2 commits July 5, 2023 20:35
@rluvaton
disable proto null for realm to avoid breaking exports
db06343
@rluvaton
disable proto null for module exports
9093d9a
@rluvaton
rluvaton force-pushed the add-proto-null-in-object-eslint-rule branch 2 times, most recently from c54494c to 9093d9a Compare July 5, 2023 17:43
rluvaton added 4 commits July 5, 2023 20:43
@rluvaton
Merge branch 'main' into add-proto-null-in-object-eslint-rule
48625ca
@rluvaton
update comment
ccd24d6
@rluvaton
move to multiline the code that keep getting bigger after fix lint
f9cb501
@rluvaton
run for the entire codebase
db021f1
This was referenced Jul 5, 2023
assert: add __proto__ null #48661
Open
http: add __proto__ null #48662
Closed
test_runner: add __proto__ null #48663
Merged
@rluvaton

rluvaton commented Jul 10, 2023

Copy link
Copy Markdown
Member Author

I'm having second thoughts on adding this globally, when I start extracting this into modules, the http was rejected due to performance implications. Also we said we don't want to add it for objects returning to userland which there are quite a few so adding eslint ignore comment will just make noise.

WDYT?

benjamingr reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@aduh95

aduh95 commented Jul 12, 2023

Copy link
Copy Markdown
Contributor

Having the rules would be useful for when we introduce new modules, where we probably want to use null-prototype objects. For example, the test runner code is the perfect place where we would benefit from this; maybe it's the only place where we end up using it, but it's still worth it imo :)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@benjamingr

benjamingr commented Jul 13, 2023

Copy link
Copy Markdown
Member

Honestly I'm personally very skeptical of __proto__: null and primordials being useful outside of web standards (where the spec may require it) unless formal security verification is performed with escape analysis.

I also would strongly prefer if we had a build step to do this instead of it being in the codebase so contributors could write "regular" code and it would become primordials in core "under the hood". Even with a build step it would need escape analysis to be useful.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rluvaton

rluvaton commented Jul 13, 2023

Copy link
Copy Markdown
Member Author

I also would strongly prefer if we had a build step to do this instead of it being in the codebase so contributors could write "regular" code and it would become primordials in core "under the hood". Even with a build step it would need escape analysis to be useful.

does having it as a build step meaning without the eslint rule and other that transform on build? if so, it's super complicated because not all places are equal - userland and some other places

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@aduh95

aduh95 commented Jul 13, 2023

Copy link
Copy Markdown
Contributor

I also would strongly prefer if we had a build step to do this instead of it being in the codebase so contributors could write "regular" code and it would become primordials in core "under the hood". Even with a build step it would need escape analysis to be useful.

That's theoretically impossible in JavaScript. It might be possible in some stricter variant of TypeScript. It was discussed by the TSC and the TSC voted against using a build step, and for using primordials as long as perf were not impacted.

benjamingr reacted with eyes emoji
All reactions
  • 👀 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ljharb

ljharb commented Jul 13, 2023

Copy link
Copy Markdown
Member

@benjamingr the security risk of NOT using proto null is that anyone can modify Object.prototype and potentially get privileged access to node internals.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@benjamingr

benjamingr commented Jul 15, 2023

Copy link
Copy Markdown
Member

@benjamingr the security risk of NOT using proto null is that anyone can modify Object.prototype and potentially get privileged access to node internals.

Right, but by doing this in a non verifiable way we are creating a false sense of "node guards against this" when in fact we don't, creating a false sense of security. If you've given someone else the chance to run code in your Node.js server you pretty much have to assume they have access to anything.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ljharb

ljharb commented Jul 15, 2023

Copy link
Copy Markdown
Member

It’s not black or white - every place it’s guarded against is an improvement, even while there remains places that it’s not.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

This pull request has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added the stale Issues and PRs marked stale due to inactivity and scheduled for automatic closure. label Jul 28, 2026
@ljharb ljharb added never-stale Issues and PRs exempt from automated stale handling. and removed stale Issues and PRs marked stale due to inactivity and scheduled for automatic closure. labels Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@ljharb ljharb ljharb left review comments
@Trott Trott Trott left review comments
@cjihrig cjihrig cjihrig left review comments
@aduh95 aduh95 aduh95 left review comments

At least 1 approving review is required to merge this pull request.

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

never-stale Issues and PRs exempt from automated stale handling. tools Issues and PRs related to the tools directory.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

8 participants

@rluvaton @ljharb @aduh95 @Trott @benjamingr @joyeecheung @cjihrig @nodejs-github-bot
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.