Skip to content

Base64 normalization (enc+dec) of the signature results in multiple mac values passing the validation #108

@ssaarela

Description

@ssaarela

The base64 encoding + decoding here (link below + base64urlUnescape function) throws 2 bits of the (SHA256) signature into the padding that gets ignored. This results in seemingly different signatures being accepted as valid.

https://github.com/jwtk/njwt/blob/master/index.js#L304

let str = 'koGE1cy2IFhBIPv_XE-kkcWbXu5Pf0hmHoiP0ZfN0b9'; // Modified mac! The correct last character is 8.
str += new Array(5 - str.length % 4).join('=');
str = str.replace(/\-/g, '+').replace(/_/g, '/');
console.log(str); // koGE1cy2IFhBIPv/XE+kkcWbXu5Pf0hmHoiP0ZfN0b9=
str = Buffer.from(str,'base64').toString('base64');
console.log(str); // koGE1cy2IFhBIPv/XE+kkcWbXu5Pf0hmHoiP0ZfN0b8=

Byte value of koGE1cy2IFhBIPv/XE+kkcWbXu5Pf0hmHoiP0ZfN0b9= ends with 00111001 00111101 while the correct koGE1cy2IFhBIPv/XE+kkcWbXu5Pf0hmHoiP0ZfN0b8= ends with 00111000 00111101 where the last 10 bits are padding. Also _ and - suffixes are accepted as valid signatures instead of the correct 8.

Would it make sense to add an extra verification that the base64urlUnescaped value equals the normalized signature to be verified? Or maybe convert the expected signature to the format required by JWT (base64url without padding) for verification?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions