-
Notifications
You must be signed in to change notification settings - Fork 3.5k
[Security] Logic Tampering via NULL byte (\u0000) Injection in cJSON_Utils Key Names #996
Description
Clear and concise description of the bug:
A logic tampering vulnerability exists in cJSON_Utils due to improper handling of NULL characters (\u0000) in JSON key names. While the cJSON core library correctly parses \u0000 and stores it as a 0x00 byte in memory, the cJSON_Utils component (specifically MergePatch and GeneratePatch) relies on standard C string functions like strcmp for key matching.
Because strcmp terminates at the first \0 byte, a cross-layer semantic inconsistency occurs: the JSON parser treats a long key containing a NULL byte as unique, but the utility logic truncates the key and incorrectly matches it against shorter, existing keys. This can lead to unauthorized data overwriting or "silent ignore" defects in differential synchronization.
Steps to reproduce the bug :
1.Modify tests/old_utils_tests.c to include a malicious payload in the merges static array:
/* Base object: {"admin": false} */
/* Malicious Patch: {"admin\u0000hacked": true} */
{"{\"admin\":false}", "{\"admin\\u0000hacked\":true}", "{\"admin\":false,\"admin\\u0000hacked\":true}"}2.Update the loop limits in merge_tests and generate_merge_tests from 15 to 16 to ensure the new test case is executed.
3.Build the project with cJSON_Utils enabled:
mkdir build && cd build
cmake .. -DENABLE_CJSON_UTILS=On -DENABLE_CJSON_TEST=On -DENABLE_SANITIZERS=On
make4.Run the utility tests:
./tests/old_utils_testsExpected behavior:
The parser should recognize "admin" and "admin\u0000hacked" as two distinct keys. The resulting merged object should be {"admin": false, "admin\u0000hacked": true}.
Observed behavior:
1.MergePatch Failure: Expected '{"admin":false,"admin\u0000hacked":true}' Was '{"admin":true}'. The patch incorrectly overwrote the value of the "admin" key.
2.GeneratePatch Failure: Expected '{"admin":false,"admin\u0000hacked":true}' Was '{"admin":false}'. The algorithm failed to detect the difference between the base and target objects, generating an empty patch.
Platform(s) (compiler version, operating system version, CPU) on which the bug was observed:
OS: Ubuntu Linux 20.04+
Compiler: GCC 9.4.0+
CPU: x86_64
cJSON release(s), commit(s), or branch(es) in which the bug was observed (always test the tip of the main branch or the latest to verify that the bug hasn't already been fixed):
cJSON(main branch)