VYPR
Moderate severityNVD Advisory· Published Aug 30, 2020· Updated Aug 4, 2024

CVE-2020-8244

CVE-2020-8244

Description

A buffer over-read in the bl npm package versions <1.2.3, <2.2.1, <3.0.1, and <4.0.3 allows attackers to read uninitialized memory by passing a negative value to consume().

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A buffer over-read in the `bl` npm package versions <1.2.3, <2.2.1, <3.0.1, and <4.0.3 allows attackers to read uninitialized memory by passing a negative value to `consume()`.

Vulnerability

Overview

CVE-2020-8244 is a buffer over-read vulnerability in the bl npm package, affecting versions earlier than 1.2.3, 2.2.1, 3.0.1, and 4.0.3 [1]. The root cause lies in the consume() method, which accepts a bytes argument that can become negative. When this negative value is used internally, it corrupts the BufferList state and causes subsequent .slice() calls to return uninitialized heap memory, effectively leaking sensitive data [2][3][4].

Exploitation

An attacker can trigger the vulnerability by supplying user input that ends up as the bytes argument to consume(). If that argument becomes negative (e.g., due to arithmetic on user-controlled data), the method fails to normalize the value and proceeds with corrupted logic [2][3][4]. No authentication is required if the attacker can inject such input into a vulnerable application. The attack surface is primarily server-side Node.js code that uses the bl library to handle streams or buffers from untrusted sources.

Impact

Successful exploitation allows an attacker to read uninitialized memory regions that may contain sensitive information such as cryptographic keys, session tokens, or other secrets from the process heap [1]. Because the leaked data is obtained through regular .slice() calls, the attacker can extract it without triggering obvious errors, making detection difficult.

Mitigation

The vulnerability has been patched in bl versions 1.2.3, 2.2.1, 3.0.1, and 4.0.3. The fix adds input validation in consume() using Math.trunc() and a check that returns early for non-positive or NaN values, and also ensures that the copy() method does not return uninitialized memory by slicing only up to bufoff [2][3][4]. Users should upgrade immediately; no known workarounds exist.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
blnpm
< 1.2.31.2.3
blnpm
>= 2.0.0, < 2.2.12.2.1
blnpm
>= 3.0.0, < 3.0.13.0.1
blnpm
>= 4.0.0, < 4.0.34.0.3

Affected products

2
  • bl/bldescription
  • ghsa-coords
    Range: < 1.2.3

Patches

3
d3e240e3b8ba

Fix unintialized memory access

https://github.com/rvagg/blMatteo CollinaAug 26, 2020via ghsa
2 files changed · +26 1
  • BufferList.js+10 1 modified
    @@ -134,19 +134,23 @@ BufferList.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) {
     
         if (bytes > l) {
           this._bufs[i].copy(dst, bufoff, start)
    +      bufoff += l
         } else {
           this._bufs[i].copy(dst, bufoff, start, start + bytes)
    +      bufoff += l
           break
         }
     
    -    bufoff += l
         bytes -= l
     
         if (start) {
           start = 0
         }
       }
     
    +  // safeguard so that we don't return uninitialized memory
    +  if (dst.length > bufoff) return dst.slice(0, bufoff)
    +
       return dst
     }
     
    @@ -188,6 +192,11 @@ BufferList.prototype.toString = function toString (encoding, start, end) {
     }
     
     BufferList.prototype.consume = function consume (bytes) {
    +  // first, normalize the argument, in accordance with how Buffer does it
    +  bytes = Math.trunc(bytes)
    +  // do nothing if not a positive number
    +  if (Number.isNaN(bytes) || bytes <= 0) return this
    +
       while (this._bufs.length) {
         if (bytes >= this._bufs[0].length) {
           bytes -= this._bufs[0].length
    
  • test/test.js+16 0 modified
    @@ -463,6 +463,22 @@ tape('test toString encoding', function (t) {
       t.end()
     })
     
    +tape('uninitialized memory', function (t) {
    +  const secret = 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) {
    +      t.fail(`Match (at ${i})`)
    +      break
    +    }
    +  }
    +  t.end()
    +})
    +
     !process.browser && tape('test stream', function (t) {
       const random = crypto.randomBytes(65534)
     
    
dacc4ac7d5fc

Fix unintialized memory access

https://github.com/rvagg/blMatteo CollinaAug 26, 2020via ghsa
2 files changed · +26 1
  • bl.js+10 1 modified
    @@ -186,18 +186,22 @@ BufferList.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) {
     
         if (bytes > l) {
           this._bufs[i].copy(dst, bufoff, start)
    +      bufoff += l
         } else {
           this._bufs[i].copy(dst, bufoff, start, start + bytes)
    +      bufoff += l
           break
         }
     
    -    bufoff += l
         bytes -= l
     
         if (start)
           start = 0
       }
     
    +  // safeguard so that we don't return uninitialized memory
    +  if (dst.length > bufoff) return dst.slice(0, bufoff)
    +
       return dst
     }
     
    @@ -233,6 +237,11 @@ BufferList.prototype.toString = function toString (encoding, start, end) {
     }
     
     BufferList.prototype.consume = function consume (bytes) {
    +  // first, normalize the argument, in accordance with how Buffer does it
    +  bytes = Math.trunc(bytes)
    +  // do nothing if not a positive number
    +  if (Number.isNaN(bytes) || bytes <= 0) return this
    +
       while (this._bufs.length) {
         if (bytes >= this._bufs[0].length) {
           bytes -= this._bufs[0].length
    
  • test/test.js+16 0 modified
    @@ -431,6 +431,22 @@ tape('test toString encoding', function (t) {
       t.end()
     })
     
    +tape('uninitialized memory', function (t) {
    +  const secret = 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) {
    +      t.fail(`Match (at ${i})`)
    +      break
    +    }
    +  }
    +  t.end()
    +})
    +
     !process.browser && tape('test stream', function (t) {
       var random = crypto.randomBytes(65534)
         , rndhash = hash(random, 'md5')
    
8a8c13c880e2

Fix unintialized memory access

https://github.com/rvagg/blMatteo CollinaAug 26, 2020via ghsa
2 files changed · +26 1
  • bl.js+10 1 modified
    @@ -185,18 +185,22 @@ BufferList.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) {
     
         if (bytes > l) {
           this._bufs[i].copy(dst, bufoff, start)
    +      bufoff += l
         } else {
           this._bufs[i].copy(dst, bufoff, start, start + bytes)
    +      bufoff += l
           break
         }
     
    -    bufoff += l
         bytes -= l
     
         if (start)
           start = 0
       }
     
    +  // safeguard so that we don't return uninitialized memory
    +  if (dst.length > bufoff) return dst.slice(0, bufoff)
    +
       return dst
     }
     
    @@ -232,6 +236,11 @@ BufferList.prototype.toString = function toString (encoding, start, end) {
     }
     
     BufferList.prototype.consume = function consume (bytes) {
    +  // first, normalize the argument, in accordance with how Buffer does it
    +  bytes = Math.trunc(bytes)
    +  // do nothing if not a positive number
    +  if (Number.isNaN(bytes) || bytes <= 0) return this
    +
       while (this._bufs.length) {
         if (bytes >= this._bufs[0].length) {
           bytes -= this._bufs[0].length
    
  • test/test.js+16 0 modified
    @@ -431,6 +431,22 @@ tape('test toString encoding', function (t) {
       t.end()
     })
     
    +tape('uninitialized memory', function (t) {
    +  const secret = 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) {
    +      t.fail(`Match (at ${i})`)
    +      break
    +    }
    +  }
    +  t.end()
    +})
    +
     !process.browser && tape('test stream', function (t) {
       var random = crypto.randomBytes(65534)
         , rndhash = hash(random, 'md5')
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.