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: replace string prototype usage with alternatives #52440

Merged
merged 1 commit into from
Apr 11, 2024

Conversation

RedYetiDev
Copy link
Member

@RedYetiDev RedYetiDev commented Apr 9, 2024

This PR replaces the use of overridable functions (in strings) with alternatives, to prevent user interference when processing cli options

@nodejs-github-bot nodejs-github-bot added the needs-ci PRs that need a full CI run. label Apr 9, 2024
@MoLow
Copy link
Member

MoLow commented Apr 9, 2024

this should be benchmarked as it is a pretty central function.
@nodejs/performance any recommendations on what benchmarks should run?

lib/internal/options.js Outdated Show resolved Hide resolved
lib/internal/options.js Outdated Show resolved Hide resolved
@RedYetiDev
Copy link
Member Author

RedYetiDev commented Apr 9, 2024

I've made a few changes based on the suggestions, there are more to be made still (such as fixing imports)

I'll go through the file tonight

@RedYetiDev
Copy link
Member Author

When ready, I'll squash

Copy link
Contributor

@Uzlopak Uzlopak left a comment

Choose a reason for hiding this comment

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

LGTM

@Uzlopak
Copy link
Contributor

Uzlopak commented Apr 9, 2024

It should be faster, but I dont think we can benchmark it as it "only" speeds up the startup time of node.

@RedYetiDev
Copy link
Member Author

RedYetiDev commented Apr 9, 2024

It should be faster, but I dont think we can benchmark it as it "only" speeds up the startup time of node.

Yes, most of the time. I've noticed that is it used during runtime (a bit).

Now that this PR has been approved, I'll squash when I get a chance

@MoLow
Copy link
Member

MoLow commented Apr 9, 2024

It should be faster, but I dont think we can benchmark it as it "only" speeds up the startup time of node.

StringPrototypeSlice is probably slower than String.prototype.slice

@RedYetiDev
Copy link
Member Author

It should be faster, but I dont think we can benchmark it as it "only" speeds up the startup time of node.

StringPrototypeSlice is probably slower than String.prototype.slice

Probably a tiny bit, but it presents less of a security issue, as a user can overwrite String.prototype.slice

@Uzlopak
Copy link
Contributor

Uzlopak commented Apr 9, 2024

Just for the performance comparison:
fastify/help#711

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

lgtm

@mcollina mcollina added the request-ci Add this label to start a Jenkins CI on a PR. label Apr 10, 2024
@RedYetiDev
Copy link
Member Author

I'll fix the lint issue and squash today.

@RedYetiDev RedYetiDev changed the title lib: use StringPrototypeStartsWith in place of .startsWith lib: replace string prototype usage with alternatives Apr 10, 2024
@RedYetiDev
Copy link
Member Author

  • Squash
  • Lint

    There was a trailing space in an IF statement

@RedYetiDev
Copy link
Member Author

I'm ready to merge when you are

@aduh95
Copy link
Contributor

aduh95 commented Apr 10, 2024

I'm ready to merge when you are

This PR requires a full CI run before landing. However, because there's a security release in preparation, the CI request is queued up (notice your PR has the request-ci Add this label to start a Jenkins CI on a PR. label). Once the security release is out, the CI will be unlocked, and it will start processing PRs.

@joyeecheung
Copy link
Member

joyeecheung commented Apr 10, 2024

I think the proposition in the PR description is misleading - primordials are not a security measure and they never will be because we will never enforce them throughout the codebase. They are only a UX enhancement (e.g. don't blow up the process just because someone patched a global prototype).

@joyeecheung
Copy link
Member

I think further special casing in JS land is not ideal - we should just add --no- entries to the options map/dictionary. And to that end we should split the map into two - one for option -> value pairs, another for option -> option information, so the first one can have additional --no- entries while the second one doesn't need it. I opened #52451 to implement that.

Copy link
Member

@benjamingr benjamingr left a comment

Choose a reason for hiding this comment

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

Hey, thanks for this PR! I don't understand this change - this code runs when Node boots before an user code runs when options values are checked (right?)

I think that implies that prototypes cannot be polluted at this point doesn't it?

@RedYetiDev
Copy link
Member Author

Hey, thanks for this PR! I don't understand this change - this code runs when Node boots before an user code runs when options values are checked (right?)

While this code is ran before runtime, it code is also used during runtime. This means that prototype pollution, while not possible for all cli arguments, is possible for some.

@benjamingr
Copy link
Member

is possible for some.

Can you give an example?

@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Apr 10, 2024
@nodejs-github-bot
Copy link
Collaborator

@RedYetiDev
Copy link
Member Author

is possible for some.

Can you give an example?

Sure! With a snippet like

const startsWith = String.prototype.startsWith;
Object.defineProperty(String.prototype, "startsWith", {
    value: function (search, pos) {
        if (search === "--no-") {
            process.nextTick(() => {
                console.log(this, search, pos);
            });
        }
        return startsWith.call(this, search, pos);
    }
})

we can see exactly what uses it during runtime.

For example, when I run fetch("https://www.google.com/"), I get the following output:

[String: '--network-family-autoselection'] --no- undefined
[String: '--insecure-http-parser'] --no- undefined
[String: '--trace-tls'] --no- undefined
[String: '--tls-keylog'] --no- undefined
[String: '--tls-cipher-list'] --no- undefined
[String: '--tls-min-v1.0'] --no- undefined
[String: '--tls-min-v1.1'] --no- undefined
[String: '--tls-min-v1.2'] --no- undefined
[String: '--tls-min-v1.3'] --no- undefined
[String: '--tls-max-v1.3'] --no- undefined
[String: '--tls-max-v1.2'] --no- undefined
[String: '--max-http-header-size'] --no- undefined

@RedYetiDev
Copy link
Member Author

out/Release/node /Users/iojs/build/workspace/node-test-commit-osx-arm/nodes/osx11/test/pummel/test-crypto-timing-safe-equal-benchmarks.js

Failed a test run, I don't think this change had anything to do with it, but idk

Copy link
Member

@benjamingr benjamingr left a comment

Choose a reason for hiding this comment

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

Ah, didn't realize, thanks makes sense (as reliability)

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@RedYetiDev
Copy link
Member Author

RedYetiDev commented Apr 11, 2024

Hi Team, I noticed that the CI bot keeps re-CI-ing this PR, isn't that a waste of resources? Is there a reason for this?

@rluvaton
Copy link
Member

It's not re-CI it's manual due to flakiness

@RedYetiDev
Copy link
Member Author

It's not re-CI it's manual due to flakiness

Ah, thanks!

@aduh95 aduh95 added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue Add this label to land a pull request using GitHub Actions. labels Apr 11, 2024
@rluvaton
Copy link
Member

@aduh95 you beat me to it with adding the commit queue label 😃

@RedYetiDev
Copy link
Member Author

Great work, everyone!

@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Apr 11, 2024
@nodejs-github-bot nodejs-github-bot merged commit bb7d748 into nodejs:main Apr 11, 2024
57 checks passed
@nodejs-github-bot
Copy link
Collaborator

Landed in bb7d748

@RedYetiDev
Copy link
Member Author

🎉

@RedYetiDev RedYetiDev deleted the patch-2 branch April 11, 2024 21:48
aduh95 pushed a commit that referenced this pull request Apr 29, 2024
PR-URL: #52440
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
marco-ippolito pushed a commit that referenced this pull request May 2, 2024
PR-URL: #52440
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
marco-ippolito pushed a commit that referenced this pull request May 3, 2024
PR-URL: #52440
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. needs-ci PRs that need a full CI run.
Projects
None yet
Development

Successfully merging this pull request may close these issues.