Open-Source Security Intelligence

Know every vulnerability
before it knows you.

DevGuard continuously monitors your dependencies and alerts you when CVEs like this one affect your stack — with real-time threat intelligence built for developers.

Search

GHSA-5vhg-9xg4-cv9m

HighCVSS 8.1 / 10
Published Jun 30, 2025·Last modified Jul 1, 2025
Affected Components(0)

No affected components available

Description

Summary

A malicious JSON-stringifyable message can be made passing on verify(), when global Buffer is buffer package

Details

This affects only environments where require('buffer') is https://npmjs.com/buffer E.g.: browser bundles, React Native apps, etc.

Buffer.isBuffer check can be bypassed, resulting in strange objects being accepted as message, and those messages could trick verify() into returning false-positive true values

v2.x is unaffected as it verifies input to be an actual Uint8Array instance

Such a message can be constructed for any already known message/signature pair There are some restrictions though (also depending on the known message/signature), but not very limiting, see PoC for example

https://github.com/bitcoinjs/tiny-secp256k1/pull/140 is a subtle fix for this

PoC

This code deliberately doesn't provide reencode for now, could be updated later

import { randomBytes } from 'crypto'
import tiny from 'tiny-secp256k1' // 1.1.6

// Random keypair
const privateKey = randomBytes(32)
const publicKey = tiny.pointFromScalar(privateKey)

const valid = Buffer.alloc(32).fill(255) // let's sign a static buffer
const signature = tiny.sign(valid, privateKey)

// Prevent processing any unverified data by fail-closed throwing
function verified(data, signature) {
  if (!Buffer.isBuffer(data)) data = Buffer.from(data, 'hex')
  if (!tiny.verify(data, publicKey, signature)) throw new Error('Signature invalid!')
  return new Uint8Array(data)
}

function safeProcess(payload) {
  const totally = JSON.parse(payload) // e.g. json over network

  const message = verified(totally, signature)
  console.log(message instanceof Uint8Array)
  console.log(Buffer.from(message).toString('utf8'))  
}

const payload = reencode(valid, "Secure contain protect")
safeProcess(payload)

Output (after being bundled):

true
Secure contain protect����

Impact

Malicious messages could crafted to be verified from a given known valid message/signature pair

Risk Scores
Base Score
8.1

The vulnerability can be exploited over the network without needing physical access. It is easy for an attacker to exploit this vulnerability. An attacker does not need any special privileges or access rights. No user interaction is needed for the attacker to exploit this vulnerability.

Threat Intelligence
6.9

Exploitation attempts have been detected. Elevated vigilance and prompt remediation are advised.

EPSS
0.21%

The exploit probability is very low. The vulnerability is unlikely to be exploited in the next 30 days.

Exploit
Not available

We did not find any exploit available. Neither in GitHub repositories nor in the Exploit-Database.

Browse More

Scan your project

Continuously monitor your dependencies and get alerted when vulnerabilities like this one affect your stack.

Checkout DevGuard