-
Notifications
You must be signed in to change notification settings - Fork 121
Security
Cista can be used to read data from untrusted sources. Therefore, it needs to have rigid checks to ensure that reading data does not lead to overflows (at deserialization or use). To improve security, Fuzzing (here: LLVM's LibFuzzer) is used. Fuzzing is implemented for different data structures. A short test is run through the CI environment for every commit.
For deserialization, there are different possibilities:
-
No checks: If you are using
cista::offset
mode, a simplereinterpret_cast<T>(ptr)
is sufficient. -
Simple checks:
cista::deserialize<T>(buf)
does the job. It checks the memory hierarchy only. All serialized data is checked so that every pointerT*
is either anullptr
or points to a valid position within the buffer with enough bytes forT
. Scalar values are checked to fit into the buffer at their position, too. Cyclic data structures are not checked "deeply" - so there might be pointers that point to data in the buffer that contains invalid pointers. -
Deep check:
cista::deserialize<T, cista::mode::DEEP_CHECK>(buf)
ensures (in addition to the simple checks) that there is no dangling pointer - even for cyclic data structures like graphs. This provides maximum security.
If you are loading trusted data and just want to make sure, that the files did not change through a memory corruption, use cista::deserialize<T, cista::mode::UNCHECKED | cista::mode::WITH_INTEGRITY>
and optionally cista::mode::WITH_VERSION
. This loads the data without bounds checking (can be omitted if it was serialized with Cista) but checks if the file contents did change using a checksum.
Note that modifying serialized data may corrupt it in unexpected ways. Therefore, it is not safe to access modified deserialized data coming from untrusted sources. However, deserializing and reading data from untrusted sources (without modifying the data) is safe.