Skip to content

JSON.stringify order is not deterministic, can lead to signature mismatches for same payload #404

Description

@kevinburke

If you pass an object as the payload to sign, it eventually gets serialized to a string by calling JSON.stringify, here: https://github.com/brianloveswords/node-jws/blob/master/lib/tostring.js#L9

The output order of JSON.stringify is not guaranteed. For example, one implementation may serialize {one: 'two', three: 'four'} as '{"one":"two","three":"four"}' and another may serialize it as '{"three":"four","one":"two"}'. The former would create a different MAC than the latter.

The latest ECMA spec for JSON.stringify says that it should produce the same order as Object.keys, which should produce the same order as for ... in, which uses Object.[[Enumerate]]() to enumerate object keys. [[Enumerate]] is a) deprecated, and b) the specification contains this note:

The mechanics and order of enumerating the properties is not specified but must conform to the rules specified below.

It might be fine if all you are doing is verifying that a generated signature is valid for the provided payload, and the verification operates on a provided string. But it would be confusing if signing the same payload generated different signatures on different Node versions, or if I generate two different JWT's using the same payload and secret key and, say, HMAC-SHA256, and expect the signatures to be equal.

In any event, you may want to provide a large warning saying that the key ordering isn't deterministic, and you may generate different signatures for the same payload and secret key pair.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions