Closed Trott closed 6 years ago
So just so people here get a sense of scale of the impact, this makes 141 modules i maintain atm print a deprecation. This is probably by far the most disruptive Node.js change I've experienced.
@ChALkeR I know you don't want to get into author shaming by publishing the list publicly, but I have to wonder if putting this list out, with concerns, couldn't encourage a community effort to update modules.
I was looking at the earlier list, and thinking that I need to roll up my sleeves and dig in.
Would a community effort to update modules create more harm than help?
@shelleyp this has nothing to do with public shaming as there is nothing bad if someone used the Buffer constructor. Not having it changed is also nothing bad as it can be a huge overhead for the maintainers as e.g., described by @mafintosh.
I actually consider building a small bot that would just open PRs in all modules with the buffer constructor. I do not think that it is feasible to manually open enough PRs to really get the upper hand for this. Having a bot should ease the pain a lot and parsing and fixing the code should be relatively straight forward in most cases. There might be some false positives but that is something that the maintainers should know when looking at the opened PR. What do others think about creating a bot for the problem?
@BridgeAR Automatic fixing is not possible in cases where the argument isn't literal, and in most cases it's not literal. Fixing that requires human intervention atm.
I am planning to make a bot that would help opening issues (or otherwise let authors know, perhaps with their consent) citing exact problematic lines on top of Gzemnid, but that would be after 10.0 release.
For now, I think that a combination of manual PRs to top packages and sending authors lists of exact lines in all their modules has a significant positive effect.
@BridgeAR I just made an assumption as to why @ChALkeR was keeping the list private. I'm sure there's another reason. And I agree, buffer constructor was an accepted coding construct.
My point was, and still is, couldn't we have a community effort to take on a list of modules that need updated and possibly see about updating as many as can be updated before Node v10 is released. That way the burden isn't solely on the module authors.
Just noting that the latest version of npm (also the next
one) is affected
@targos Yes, mostly due to deps. That is known. I filed some issues about that already and got 3 at least PRs merged in npm deps =).
@shelleyp Generally speaking, there could be security implications in entries of old Buffer API usage, this is the main reason why I am not sharing an easy to consume list of all of those.
Re: community effort, I share a public list of specific top-impact packages after initial review of those, that list is available at https://github.com/nodejs/node/issues/19079#issuecomment-374536006 and includes the most important packages, so that people willing to help would be able to file PRs to those. Once those are processed β I will add new entries to the public list.
@ChALkeR Ah, slapping head, of course. Nothing like providing a map showing people where they can wreck havoc.
Too bad, though. It could have been a good community exercise.
Sounds good on the list you can provide. I'll link to it from an writing I'm doing on Buffer constructors and the new Node version.
@targos @Trott npm primarily depends on the flush-write-stream geting published (the fix already landed, ping @mafintosh for the semver-patch version release).
After that, with a bit lower significance (but still very high) β at sshpk
update. Fixing sshpk
is very important =). Upd: I'm on it.
FYI, I'm fine publishing a map of my own stuff. There is no way I'm getting to get anywhere close to updating them in time for this release.
I second @mafintosh's concerns and I think these changes will be hugely disruptive to userland. The other thing to consider is that the ecosystem is largely a product of people gifting their work for free to support a commons. I think it's hugely disrespectful to demand that people update their code because of changes in node core in this way, and there will be a significant, non-trivial number of packages that will never update. That problem is compounded by dependencies of dependencies, where any package in your dependency graph could emit these warnings and you may be relatively powerless to prevent these issues aside from forking every package along that critical path to the offending module.
If this change is so important to node core, has anyone considered paying people to do this work? This is a very large, disruptive change that will very negatively impact the ecosystem unless a lot of effort and compensation is put into a coordinated effort.
@substack This change is important not to node core (which also largely consists of people gifting their work for free, surprize-surprize), but to ecosystem to reduce the security impact and the potential damage caused on the ecosystem by insecure Buffer API usage, and to people using those modules from the ecosystem. This is not something core has decided to do at a whim. I suggest performing some research before writing condemning comments.
I use a tool https://snyk.io/, to scan my projects for vulnerable dependencies. These guys have a vulnerability database with is matched with your projects' package.json
, and can find a bunch of vulnerabilities in your projects dependencies, including but not limited to use of the Buffer constructor.
I'd say we scan our projects if possible to find which packages are vulnerable and start opening issues and PRs?
P.S. I'm not affiliated to Snyk.
@AyushG3112 Not all usage of Buffer constructor is reported there, and even not all insecure usage of Buffer constructor is. But fixing those would be a good thing.
It's worth pointing out that the Buffer constructor is in it self not insecure. The issue is that it's easy to write code that's insecure by accident when using the Buffer constructor. So Snyk (and similar) will never mark all modules that uses the of Buffer constructor as insecure.
I have been pro runtime deprecation for this in 10.0.0 largely because... in an ideal world, that's exactly the right thing to do. Unfortunately, the way runtime deprecations are currently handled by core makes this entirely too disruptive right now. After going through an evaluating the position @mafintosh is in on this, I'm forced to admit that I'm reconsidering my position on this for 10.0.0. For 10.0.0, we should keep the --pending-deprecation
gate on the warning but we shouldn't leave it at that. We need to revisit how we do runtime deprecations in general and put focus on developing a better approach to handling these. @mafintosh's suggestion that we emit the process warning only for usercode is a viable path. Changing the way we emit deprecation warnings is another.
Not deprecating legacy APIs is not a solution. Node.js is not a sandboxed environment. Our trust model means that we must be able to deprecate and make breaking changes when it is necessary to do so.
If we aren't going to "runtime-deprecate" something that's been "pending-deprecation" for years then we made the wrong choice in marking it for "pending-deprecation" to begin with. We should either "runtime-deprecate" it in 10 or remove it from pending deprecation entirely.
The point is that nothing will change if we keep postponing this. The same problem and discussion will arise again in version 11, then in 12 and so on. We should draw a line and stick with it or not draw it at all.
@geek @lpinca what @jasnell is saying is that we should consider having a better way of doing deprecation first, not that we shouldn't deprecate it at all or just postpone it
Note that Node can also do this gradually:
new Buffer
when not in node_modules
in v10.new Buffer
entirely in 11.I agree this is frustrating - but I still shudder when thinking about graceful-fs and ecosystem breakage. I get that new Buffer
has been deprecated for a while now - but the fact authors like @mafintosh and @substack feel that this is sudden and threatening to their work is also a very valid concern IMO.
@substack
The other thing to consider is that the ecosystem is largely a product of people gifting their work for free to support a commons. I think it's hugely disrespectful to demand that people update their code because of changes in node core in this way, and there will be a significant, non-trivial number of packages that will never update.
While I agree with that part (as a part of the ecosystem) note that this is also largely the case for Node.js core, most of us are doing work for free to support a commons because we believe it helps better - so it's important to remember that the people for a runtime deprecation are in the exact same boat here.
I may be joking so feel free to ignore me, but there is another way to deprecate things (Inspired by https://twitter.com/johnregehr/status/920691341738123264?lang=en):
diff --git a/lib/buffer.js b/lib/buffer.js
index b369d27a1e..39227f1c2f 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -172,7 +172,11 @@ const doFlaggedDeprecation =
* Deprecation Code: DEP0005
**/
function Buffer(arg, encodingOrOffset, length) {
- doFlaggedDeprecation();
+ let num = 0;
+ for (let i = 0; i < 1e7; ++i) {
+ num += Date.now();
+ }
+ require('assert')(num); // in case it gets optimized away
// Common case.
if (typeof arg === 'number') {
if (typeof encodingOrOffset === 'string') {
Delaying this won't help, the situation becomes worse over time. I actually measured the ecosystem usage and I know what I am talking about, this is not just something I am imagining out of my head.
Any other approach won't help to resolve those potential security issues (which sum up into large security holes in real software) β as developers of deps won't get informed and won't fix those. Users should be informed of the location of potentially unsafe code in their deps, and the warning is way to achieve that.
The only way to mitigate the huge security impact of this problem is to actually fix all the modules. Delaying only suggests not doing that. The module authors are not happy that they need to fix the code, but the warning is just the messenger.
Without the warning, this issue will just continue piling up.
Ecosystem usage of unsafe Buffer API grows over time by itself, waiting more would actually mean more porting work done by ecosystem module authors, not less.
What we could do is to gradually deprecate it in 10, but as a dependency over time, not 10.x version. I already metioned that earlier and will elaborate again today β but the intention is to decrease the number of users seeing the deprecation warnings, not to reduce or delay the porting work.
There is nothing we can do with module authors having to upgrade the code (except for helping them to do that, by providing PRs, exact usage lists and things like an excelent tool by @joyeecheung). The deprecation is not the reason why that code needs to be upgraded in the ecosystem. The massive amount of potential security issues that transform into a significant number of real security holes is that in turn affect real people out there is.
And if we don't do a runtime deprecation now β the issue would become just worse with more code needing to be ported and more work needing to be done.
@joyeecheung You are not the first one mentioning that, and no β synchronously waiting is going to cause more impact and more havoc to the ecosystem than just printing a concise and suppressible warning to the console.
The proposal I'm at right now:
--pending-deprecation
node-modules
. The process.on('warning')
event would still be emitted. When --trace-deprecation
or --throw-deprecation
is used, the console output for node-modules
would be enabled. Point being, it's explicitly opt-in.@jasnell @ChALkeR it sounds to me like deprecation for non node_modules
runtime deprecation is a good strategy for 10.0. I still feel like we should runtime deprecate it (inside node_modules) eventually though.
@benjamingr ... deprecating is usercode and not node-modules would end up having the side-effect of causing the deprecation warning to show up in test runs for the modules (e.g. every time someone runs npm test
). That, along with an active effort to help userland move to the new APIs would hopefully allow us to make some progress on this.
Modify core's runtime deprecation warnings such that the console output is not emitted by default for code running in
node-modules
.
You know that's trickier than this -- we mostly do runtime deprecations to warn about API usage that is going to be broken in some way, which is also something that application users do want to know about; this does not fall into that category.
We could and should consider doing per-case decisions for this, though.
One thought I had was to modify the pending deprecation mechanism such that it would always emit when running as user-code and only emit for node-modules when the --pending-deprecation
flag was used.
@benjamingr No, just excluding node_modules
is not a good strategy β that would mean that most of the packages won't be fixed for yet another 6 months if not a year. See the discussion at https://github.com/nodejs/node/pull/15346#issuecomment-369559160.
See also https://github.com/nodejs/node/issues/19079#issuecomment-373938852 for an alternate suggestion (excluding node_modules
at 99% chance and at 1% β printing the warning for that).
I'm π on making it node_modules
only. However, I'm also ok in runtime deprecate it in 10.0.0 before we go LTS. I'm also ok on @ChALkeR suggestion in https://github.com/nodejs/node/issues/19079#issuecomment-375022270. We need to do something on this, as it is getting out of track. They must be deprecated eventually.
This does not change the basic economics of what @substack described in https://github.com/nodejs/node/issues/19079#issuecomment-374947889. This is a lot of work, and someone has to do it. We can decide that we will not deprecate them, because the amount of legacy code to change is too big. IMHO, buying 6 months is a good strategy if we spend 6 months fixing the issue everywhere. If we don't, then we have just delayed the problem. I'm -1 on that.
Revert the runtime deprecation for 10.0.0.
@jasnell Nothing to revert yet because it hasn't landed. So you can get to work on that new runtime deprecation warning setup straightaway. :-D
EDIT: This next paragraph is not directed at @jasnell. It's an FYI for anyone and everyone.
By the way, to repeat something that @addaleax wrote: Put export NODE_PENDING_DEPRECATION=1
in your .bashrc
to get a feel for just how noisy/disruptive this change would be right now. (That's not necessarily an argument against the change. You could also take it as "OMG, there's so much Buffer ctor usage out there, we need to do something!" It's a piece of information.)
Nothing to revert yet ...
Ah, good, I couldn't remember whether or not that had actually landed yet. That makes things easier ;-)
@jasnell
After going through an evaluating the position @mafintosh is in on this, I'm forced to admit that I'm reconsidering my position on this for 10.0.0.
Modify core's runtime deprecation warnings such that the console output is not emitted by default for code running in node-modules.
Could you clarify how exactly hiding warnings for node_modules
would help @mafintosh?
At the TSC meeting today, there was consensus (14 TSC attendees, no objections) that the runtime deprecation in 10.0.0 should only warn for code outside of node_modules
to reduce the impact on end users for now at least, but to make it less likely that new code will use Buffer
constructor.
@nodejs/tsc in case there are any objection, questions, comments, etc.
@Trott The full deprecation still hasn't landed, so perhaps this should remain open until then?
TSC approved runtime-deprecation of Buffer constructor for 10.0.0.
Here's the tracking list. @nodejs/tsc: Feel free to edit this to add more items to the checklist. I'm just getting it started, really.
new Buffer()
now zero-filling and a documentation deprecation for it). We're likely to see a lot of comments like https://twitter.com/shelleypowers/status/969568430105006080.What have I missed?
@nodejs/community-committee @nodejs/buffer
FWIW, here's how the TSC voted: