The case against using JSON in smart contracts #143
Replies: 3 comments
-
The migration path that I see from JSON to Borsh is by introducing metadata standard. Once the metadata standard is widely adopted by contracts, we can start upgrading tools to use this metadata. The metadata may define the serialization format of the contract, e.g. JSON or Borsh. Then the tool can use metadata to serialize arguments properly. But we can't force ourselves into Borsh before the actual metadata exists, because it will be really painful transition. |
Beta Was this translation helpful? Give feedback.
-
From a strategic perspective, I agree. I think most would agree ... but the problem is everyone is married to JSON (for the time being). I believe it will happen eventually, but will take time ... I remember the days when XML dominated. A good first step would be to introduce the idea through the metadata standard, and let the users and applications decide. |
Beta Was this translation helpful? Give feedback.
-
Another security issue with JSON: #144. |
Beta Was this translation helpful? Give feedback.
-
Currently, most NEAR contracts use JSON to serialize their arguments and return values. There are various problems with this. Some of them were discussed before, for example, JSON libraries being large (thus contributing significantly to the contract size) and slow (contributing to the gas usage). However, this post is about security implications of using JSON.
One of the good properties of Borsh is that is has an (almost) precise specification. Thus, everyone should agree on which byte sequences are valid Borsh encodings of a specific type, and what values they represent. Unfortunately, this is not the case for JSON. Different JSON implementations behave differently, and this includes not only different libraries but also different versions of the same library.
What does it mean for smart contracts? Well, for starters, the precise behavior of a contract may depend on which version of JSON library it is linked against. This shouldn't be a problem by itself, because such differences will only happen on some specially constructed inputs. But what if some other tool were to parse contract inputs? For example, we may want the explorer to track token transfers. For this, it may need to parse inputs to the calls to token functions. If the implementation of the JSON parser used for this is different from the implementation used by the token contract itself (which may be different for different tokens), an attacker can construct a call that will be interpreted differently by the contract and by the explorer, potentially breaking it.
Another example: there are currently plans to potentially use ETH as a native token in the EVM. If this happens, the EVM implementation will have to use NEP-21 API to call the token functions and then parse their output as JSON. In this case, the precise behavior of the parser may depend on which precise version of JSON library nearcore is linked against, which may result in consensus failure.
In general, neither JSON itself nor specific JSON implementations were designed for consensus-critical applications. The faster we get rid of JSON on-chain, the fewer problems we will have down the road.
Beta Was this translation helpful? Give feedback.
All reactions