Warning Node Has Slots In Importing State

Posted on
  1. Warning Node Has Slots In Importing Statement
  2. Warning Node Has Slots In Importing Staten Island
  3. Warning Node Has Slots In Importing State Park
Edit on GitHub

Overview

This guide explains how to migrate to safe Buffer constructor methods. The migration fixes the following deprecation warning:

The Buffer() and new Buffer() constructors are not recommended for use due to security and usability concerns. Please use the new Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() construction methods instead.

The snippet asks you to specify the name of the generator. Make sure that your project has 'yo' installed in its nodemodules folder and that your generated project has been installed for debugging by running npm link in the project folder. Gulp task: Debug a gulp task. Make sure that your project has 'gulp' installed in its nodemodules folder. You can perform an import while the system is up and running. An import operation modifies information on the management plane only. Some modifications caused by an import operation, such as a change to a vNIC assigned to a server, can cause a server reboot or other operations that disrupt traffic. You cannot schedule an import operation. However, when using globals, we still recommend using npm, especially if you use nvm (Node Version Manager). Use git for repository management and make regular commits, it is like taking notes on the process and lets you revert to a previous state in case you get stuck. Use Quasar boot files for any pre-mounting app routines.

  • Variant 1: Drop support for Node.js ≤ 4.4.x and 5.0.0 — 5.9.x (recommended)

Finding problematic bits of code using grep

Just run grep -nrE '[^a-zA-Z](Slow)?Buffers*(' --exclude-dir node_modules.

It will find all the potentially unsafe places in your own code (with some considerably unlikelyexceptions).

Finding problematic bits of code using Node.js 8

If you’re using Node.js ≥ 8.0.0 (which is recommended), Node.js exposes multiple options that help with finding the relevant pieces of code:

  • --trace-warnings will make Node.js show a stack trace for this warning and other warnings that are printed by Node.js.
  • --trace-deprecation does the same thing, but only for deprecation warnings.
  • --pending-deprecation will show more types of deprecation warnings. In particular, it will show the Buffer() deprecation warning, even on Node.js 8.

You can set these flags using environment variables:

Finding problematic bits of code using linters

ESLint rules no-buffer-constructorornode/no-deprecated-apialso find calls to deprecated Buffer() API. Those rules are included in some presets.

There is a drawback, though, that it doesn't alwayswork correctly when Buffer isoverridden e.g. with a polyfill, so recommended is a combination of this and some other methoddescribed above.

Variant 1: Drop support for Node.js ≤ 4.4.x and 5.0.0 — 5.9.x

This is the recommended solution nowadays that would imply only minimal overhead.

The Node.js 5.x release line has been unsupported since July 2016, and the Node.js 4.x release line reaches its End of Life in April 2018 (→ Schedule). This means that these versions of Node.js will not receive any updates, even in case of security issues, so using these release lines should be avoided, if at all possible.

What you would do in this case is to convert all new Buffer() or Buffer() calls to use Buffer.alloc() or Buffer.from(), in the following way:

  • For new Buffer(number), replace it with Buffer.alloc(number).
  • For new Buffer(string) (or new Buffer(string, encoding)), replace it with Buffer.from(string) (or Buffer.from(string, encoding)).
  • For all other combinations of arguments (these are much rarer), also replace new Buffer(...arguments) with Buffer.from(...arguments).

Note that Buffer.alloc() is also faster on the current Node.js versions thannew Buffer(size).fill(0), which is what you would otherwise need to ensure zero-filling.

Enabling ESLint rule no-buffer-constructorornode/no-deprecated-apiis recommended to avoid accidental unsafe Buffer API usage.

There is also a JSCodeshift codemodfor automatically migrating Buffer constructors to Buffer.alloc() or Buffer.from().Note that it currently only works with cases where the arguments are literals or where theconstructor is invoked with two arguments.

If you currently support those older Node.js versions and dropping support for them is not possible, or if you support older branches of your packages, consider using Variant 2or Variant 3 on older branches, so people using those older branches will also receivethe fix. That way, you will eradicate potential issues caused by unguarded Buffer API usage andyour users will not observe a runtime deprecation warning when running your code on Node.js 10.

Variant 2: Use a polyfill

Warning

There are three different polyfills available:

  • safer-buffer is a drop-in replacement for theentire Buffer API, that will throw when using new Buffer().

    You would take exactly the same steps as in Variant 1, but with a polyfillconst Buffer = require('safer-buffer').Buffer in all files where you use the new Buffer API.

    Do not use the old new Buffer() API. In any files where the line above is added,using old new Buffer() API will throw.

  • buffer-from and/orbuffer-alloc areponyfills for their respective part of the Buffer API. You only needto add the package(s) corresponding to the API you are using.

    You would import the module needed with an appropriate name, e.g.const bufferFrom = require('buffer-from') and then use that instead of the call tonew Buffer(), e.g. new Buffer('test') becomes bufferFrom('test').

    A downside with this approach is slightly more code changes to migrate off them (as you would beusing e.g. Buffer.from() under a different name).

  • safe-buffer is also a drop-in replacement forthe entire Buffer API, but using new Buffer() will still work as before.

    A downside to this approach is that it will allow you to also use the older new Buffer() APIin your code, which is problematic since it can cause issues in your code, and will startemitting runtime deprecation warnings starting with Node.js 10(read more here).

Note that in either case, it is important that you also remove all calls to the old BufferAPI manually — just throwing in safe-buffer doesn't fix the problem by itself, it just providesa polyfill for the new API. I have seen people doing that mistake.

Enabling ESLint rule no-buffer-constructorornode/no-deprecated-apiis recommended.

Don't forget to drop the polyfill usage once you drop support for Node.js < 4.5.0.

Variant 3 — Manual detection, with safeguards

This is useful if you create Buffer instances in only a few places (e.g. one), or you have your ownwrapper around them.

Buffer(0)

This special case for creating empty buffers can be safely replaced with Buffer.concat([]), whichreturns the same result all the way down to Node.js 0.8.x.

Buffer(notNumber)

Before:

After:

encoding is optional.

Note that the typeof notNumber before new Buffer() is required (for cases when notNumber argument is nothard-coded) and is not caused by the deprecation of Buffer constructor — it's exactly why theBuffer constructor is deprecated. Ecosystem packages lacking this type-check caused numeroussecurity issues — situations when unsanitized user input could end up in the Buffer(arg) createproblems ranging from DoS to leaking sensitive information to the attacker from the process memory.

When notNumber argument is hardcoded (e.g. literal 'abc' or [0,1,2]), the typeof check canbe omitted.

Also, note that using TypeScript does not fix this problem for you — when libs written inTypeScript are used from JS, or when user input ends up there — it behaves exactly as pure JS, asall type checks are translation-time only and are not present in the actual JS code which TScompiles to.

Warning Node Has Slots In Importing Statement

Buffer(number)

Node

For Node.js 0.10.x (and below) support:

Otherwise (Node.js ≥ 0.12.x):

Regarding Buffer.allocUnsafe()

Be extra cautious when using Buffer.allocUnsafe():

  • Don't use it if you don't have a good reason to
    • e.g. you probably won't ever see a performance difference for small buffers, in fact, thosemight be even faster with Buffer.alloc(),
    • if your code is not in the hot code path — you also probably won't notice a difference,
    • keep in mind that zero-filling minimizes the potential risks.
  • If you use it, make sure that you never return the buffer in a partially-filled state,
    • if you are writing to it sequentially — always truncate it to the actual written length

Errors in handling buffers allocated with Buffer.allocUnsafe() could result in various issues,ranged from undefined behavior of your code to sensitive data (user input, passwords, certs)leaking to the remote attacker.

Note that the same applies to new Buffer() usage without zero-filling, depending on the Node.jsversion (and lacking type checks also adds DoS to the list of potential problems).

FAQ

Warning Node Has Slots In Importing Staten Island

What is wrong with the Buffer constructor?

Warning Node Has Slots In Importing State

The Buffer constructor could be used to create a buffer in many different ways:

  • new Buffer(42) creates a Buffer of 42 bytes. Before Node.js 8, this buffer containedarbitrary memory for performance reasons, which could include anything ranging fromprogram source code to passwords and encryption keys.
  • new Buffer('abc') creates a Buffer that contains the UTF-8-encoded version ofthe string 'abc'. A second argument could specify another encoding: for example,new Buffer(string, 'base64') could be used to convert a Base64 string into the originalsequence of bytes that it represents.
  • There are several other combinations of arguments.

This meant that in code like var buffer = new Buffer(foo);, it is not possible to tellwhat exactly the contents of the generated buffer are without knowing the type of foo.

Sometimes, the value of foo comes from an external source. For example, this functioncould be exposed as a service on a web server, converting a UTF-8 string into its Base64 form:

Note that this code does not validate the type of req.body.string:

  • req.body.string is expected to be a string. If this is the case, all goes well.
  • req.body.string is controlled by the client that sends the request.
  • If req.body.string is the number50, the rawBytes would be 50 bytes:
    • Before Node.js 8, the content would be uninitialized
    • After Node.js 8, the content would be 50 bytes with the value 0

Because of the missing type check, an attacker could intentionally send a numberas part of the request. Using this, they can either:

  • Read uninitialized memory. This will leak passwords, encryption keys and otherkinds of sensitive information. (Information leak)
  • Force the program to allocate a large amount of memory. For example, when specifying500000000 as the input value, each request will allocate 500MB of memory.This can be used to either exhaust the memory available of a program completelyand make it crash, or slow it down significantly. (Denial of Service)

Both of these scenarios are considered serious security issues in a real-worldweb server context.

When using Buffer.from(req.body.string) instead, passing a number will alwaysthrow an exception instead, giving a controlled behavior that can always behandled by the program.

The Buffer() constructor has been deprecated for a while. Is this really an issue?

Warning Node Has Slots In Importing State Park

Surveys of code in the npm ecosystem have shown that the Buffer() constructor is stillwidely used. This includes new code, and overall usage of such code has actually beenincreasing.