node-jose icon indicating copy to clipboard operation
node-jose copied to clipboard

Can validate an invalid signature...

Open wellcaffeinated opened this issue 3 years ago • 2 comments

Am I mistaken, or is this not right?

Affected version: 2.0.0

async function test() {
  const payload = Uint8Array.from([0, 3, 4, 2])
  const key = await jose.JWK.createKey('EC', 'P-256')
  const pk = await jose.JWK.asKey(key.toJSON())
  console.log(pk)
  const sig = await jose.JWS.createSign({ format: 'compact' }, key)
    .update(payload)
    .final()
  console.log(sig)
  const res = await jose.JWS.createVerify(pk).verify(sig+'12') // APPEND GARBAGE DATA TO SIGNATURE
  // still get result.
  console.log(
    res,
    res.payload.toString('hex'),
    Buffer.from(payload).toString('hex')
  )
}

test()

wellcaffeinated avatar Feb 03 '22 21:02 wellcaffeinated

+1, we came across the same issue, if we add extra charater at the end of the signature, it's still be verified

zkwzk avatar Jul 22 '22 02:07 zkwzk

That's because the library doesn't check if the signature length matches the actual digest. You can add checks if you want it to fail, for example in hmac.js, you can update the logic from:

  function compare(len, expected, actual) {
    len = (len || CONSTANTS.HASHLENGTH[hash]) / 8;
    var valid = true;
    for (var idx = 0; len > idx; idx++) {
      valid = valid && (expected[idx] === actual[idx]);
    }
    return valid;
  }

to

  function compare(len, expected, actual) {
    len = (len || CONSTANTS.HASHLENGTH[hash]) / 8;
    if (expected.length !== actual.length) { // just add a check here
        return false;
    }
    var valid = true;
    for (var idx = 0; len > idx; idx++) {
      valid = valid && (expected[idx] === actual[idx]);
    }
    return valid;
  }

Jefferson111 avatar Jul 18 '23 03:07 Jefferson111