TinyJson: Stack overflow from unbounded recursion in ParseValue/ParseObject
Summary
Nakama.TinyJson.JsonParser.ParseValue and ParseObject call each other recursively with no depth limit. On platforms with limited stack size (Android ARM64 with IL2CPP = 1MB default), moderately nested JSON or types with nested object fields cause a StackOverflowException that crashes the application.
This is the same vulnerability class as CVE-2024-7254 (Google Protobuf unbounded recursion DoS).
Impact
- ~80 crashes/day across two production Android games (build 1.4.210)
- Affects both games because
Nakama.dll is shared
- Crash in
[libil2cpp.so] — stack overflow manifests as a native crash, not a managed exception
- Same Crashlytics issue ID appears across multiple games using the same Nakama client version
Reproduction
Any JSON payload parsed by TinyJson with sufficient nesting depth will trigger this. The exact threshold depends on platform stack size:
- Android ARM64 IL2CPP: ~1MB stack → crashes at relatively shallow depth
- Desktop/Editor: larger stack → harder to reproduce without deeply nested payloads
Root Cause (IL Analysis)
Decompiled Nakama.dll v3.21.1 with System.Reflection.Metadata:
ParseValue (1160 bytes IL): calls ParseObject when JSON token is {
ParseObject (267 bytes IL): calls ParseValue for each field value
- Neither method has a recursion depth check
ParseObject is small (~32 bytes ARM64 = ~8 instructions) — the mutual recursion burns through the stack quickly
Suggested Fix
Add a [ThreadStatic] depth counter to ParseValue:
[ThreadStatic] static int _parseDepth;
const int MaxParseDepth = 64;
object ParseValue(Type type, string json)
{
if (++_parseDepth > MaxParseDepth)
{
_parseDepth--;
return null; // or throw a descriptive exception
}
try
{
// existing ParseValue logic
}
finally
{
_parseDepth--;
}
}
This matches the approach used to fix CVE-2024-7254 in protobuf-java (recursion depth limit).
Workaround
We are currently maintaining a patched build of Nakama.dll from the v3.21.1 tag with the above depth guard applied. This is fragile — the patch must be re-applied on every SDK update.
Environment
- Nakama .NET Client: 3.21.1 (via nakama-unity)
- Unity: 6000.4.0f1
- Platform: Android ARM64 (IL2CPP)
- Crashlytics issue: 8f0be5b4
TinyJson: Stack overflow from unbounded recursion in ParseValue/ParseObject
Summary
Nakama.TinyJson.JsonParser.ParseValueandParseObjectcall each other recursively with no depth limit. On platforms with limited stack size (Android ARM64 with IL2CPP = 1MB default), moderately nested JSON or types with nested object fields cause aStackOverflowExceptionthat crashes the application.This is the same vulnerability class as CVE-2024-7254 (Google Protobuf unbounded recursion DoS).
Impact
Nakama.dllis shared[libil2cpp.so]— stack overflow manifests as a native crash, not a managed exceptionReproduction
Any JSON payload parsed by TinyJson with sufficient nesting depth will trigger this. The exact threshold depends on platform stack size:
Root Cause (IL Analysis)
Decompiled
Nakama.dllv3.21.1 withSystem.Reflection.Metadata:ParseValue(1160 bytes IL): callsParseObjectwhen JSON token is{ParseObject(267 bytes IL): callsParseValuefor each field valueParseObjectis small (~32 bytes ARM64 = ~8 instructions) — the mutual recursion burns through the stack quicklySuggested Fix
Add a
[ThreadStatic]depth counter toParseValue:This matches the approach used to fix CVE-2024-7254 in protobuf-java (recursion depth limit).
Workaround
We are currently maintaining a patched build of
Nakama.dllfrom the v3.21.1 tag with the above depth guard applied. This is fragile — the patch must be re-applied on every SDK update.Environment