Add option to server to disable JSON responses
Add option to server to disable JSON responses to avoid potential DoS vector.
From https://github.com/ChainSafe/lodestar/issues/5128#issuecomment-1758069716 and moved out todos from https://github.com/ChainSafe/lodestar/pull/6749 as it is not required to be implemented as part of PR and requires more discussion / clarity on what are the expectations.
While this is quite simple to implement by updating SUPPORTED_MEDIA_TYPES
https://github.com/ChainSafe/lodestar/blob/8b59f500e22175d61155410db9fe587facf3e3c9/packages/api/src/utils/headers.ts#L14
it is not clear to me if we can disable json globally, because
- users might wanna query data as json (it's just simpler in a lot of cases)
- some apis do not support ssz because it's not technically possible (no json to ssz mapping), essentially disabling those completely
Since the main goal of this is to make it more difficult to DoS / crash public Lodestar nodes, we might wanna limit this to just APIs like getStateV2 . There are also other offenders like getStateValidators which do not support ssz but can bring down the node quite easily.
Thinking about this more, the main issue why JSON is a DoS vector is due to serialization (JSON.stringify) because it takes a lot of memory if you do this for the beacon state or a huge validator array. We don't necessarily need to disable JSON if we can figure out a way to avoid passing huge objects like the state into stringify and throw an error instead.
This would address both concerns brought up in the issue and even allow to still use getStateValidators but it has to be queried for a subset of validators by passing pubkeys, and for getStateV2 it would mean it can only return SSZ on holesky and mainnet but it can still returns JSON data in dev mode, smaller networks (e.g. sepolia), or kurtosis.
if we can figure out a way to avoid passing huge objects like the state into stringify and throw an error instead.
So far, I have not found a solution for this that is cheap enough to add to our api as it requires to iterate over the objects (or convert to a Buffer) which would be a DoS vector itself, and affect api latency.