jose
jose copied to clipboard
Deterministic JSON Stringify
A recurring problem that has been seen with regards to hashes and signatures is when properties get switched around between JSON.stringify
calls which results in hashes not matching and signatures not verifying successfully despite semantically identical objects.
For example, an object { alg: 'RS256', kid: 'abcd' }
could be stringified as:
{"alg":"RS256","kid":"abcd"}
or
{"kid":"abcd","alg":"RS256"}
The result of the stringify operation depends on the original order of the properties in the JSON string (my understanding is that the order is preserved) and the order in which properties are added to the object.
My recommendation is that we replace our stringify calls with our own deterministic stringify function, or one that we import such as json-stable-stringify.
That's a really good idea. (i'd vote for json-stable-stringify)
I don't doubt there are cases where this has been a problem, and have often wondered if we'd have to squash bugs caused thusly. In practice, it hasn't bitten me personally.
One reason for this may be the way modinha
and json-document
schemas are traversed to read/copy data when initializing. That would minimize the sort of property reordering you're talking about. In fact, it may be a deterministic function on it's own.
I could see such schemes causing problems interoperating with JSON data stringified in the "usual" way.
Just for posterity, can you point to a concrete case or two where JSON.stringify()
over the same state has resulted in two different values?
@christiansmith take a look at:
https://github.com/anvilresearch/jose/blob/master/test/jose/JWDSpec.js#L24-L40
Swap lines 34 and 35 and watch the world burn.