CVE-2020-1915
Description
An out-of-bounds read in the JavaScript Interpreter in Facebook Hermes prior to commit 8cb935cd3b2321c46aa6b7ed8454d95c75a7fca0 allows attackers to cause a denial of service attack or possible further memory corruption via crafted JavaScript. Note that this is only exploitable if the application using Hermes permits evaluation of untrusted JavaScript. Hence, most React Native applications are not affected.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
An out-of-bounds read in Facebook Hermes JavaScript interpreter allows denial of service or memory corruption via crafted JavaScript, but only if untrusted code is evaluated.
Vulnerability
Overview
CVE-2020-1915 is an out-of-bounds read vulnerability in the JavaScript Interpreter of Facebook Hermes, a JavaScript engine optimized for React Native [4]. The root cause lies in the putComputedWithReceiver_RJS function, which mishandles a scenario where both internalSetter and Proxy are true. Specifically, when putComputed is called on a proxy whose target's prototype is an array with a property named 'length', the internal setter flag is set and the receiver is a proxy. The original code did not correctly delegate to the proxy's defineOwnProperty, leading to an out-of-bounds read [1][3].
Exploitation
Conditions
Exploitation requires the attacker to supply crafted JavaScript that triggers this specific code path. The vulnerability is only exploitable if the application using Hermes permits evaluation of untrusted JavaScript. According to the advisory, most React Native applications do not evaluate untrusted JavaScript, so they are not affected [1].
Impact
Successful exploitation could cause a denial of service or potentially lead to further memory corruption [1].
Mitigation
The issue was fixed in commit 8cb935cd3b2321c46aa6b7ed8454d95c75a7fca0 [3]. Users should update Hermes to a version that includes this fix. The fix was tracked in GitHub issue #373 [2] and is included in Hermes releases after the commit date.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
hermes-enginenpm | < 0.7.2 | 0.7.2 |
Affected products
2- Facebook/Hermesv5Range: commit prior to 8cb935cd3b2321c46aa6b7ed8454d95c75a7fca0
Patches
18cb935cd3b23Handle set where internalSetter and Proxy are both true
2 files changed · +29 −15
lib/VM/JSObject.cpp+20 −15 modified@@ -1699,6 +1699,24 @@ CallResult<bool> JSObject::putComputedWithReceiver_RJS( if (LLVM_UNLIKELY( desc.flags.internalSetter || receiverHandle->isHostObject() || receiverHandle->isProxyObject())) { + // If putComputed is called on a proxy whose target's prototype + // is an array with a propname of 'length', then internalSetter + // will be true, and the receiver will be a proxy. In that case, + // proxy wins. + if (receiverHandle->isProxyObject()) { + if (*descDefinedRes) { + dpf.setValue = 1; + } else { + dpf = DefinePropertyFlags::getDefaultNewPropertyFlags(); + } + return JSProxy::defineOwnProperty( + receiverHandle, + runtime, + nameValPrimitiveHandle, + dpf, + valueHandle, + opFlags); + } SymbolID id{}; LAZY_TO_IDENTIFIER(runtime, nameValPrimitiveHandle, id); if (desc.flags.internalSetter) { @@ -1709,23 +1727,10 @@ CallResult<bool> JSObject::putComputedWithReceiver_RJS( desc.castToNamedPropertyDescriptorRef(), valueHandle, opFlags); - } else if (receiverHandle->isHostObject()) { - return vmcast<HostObject>(receiverHandle.get())->set(id, *valueHandle); } assert( - receiverHandle->isProxyObject() && "descriptor flags are impossible"); - if (*descDefinedRes) { - dpf.setValue = 1; - } else { - dpf = DefinePropertyFlags::getDefaultNewPropertyFlags(); - } - return JSProxy::defineOwnProperty( - receiverHandle, - runtime, - nameValPrimitiveHandle, - dpf, - valueHandle, - opFlags); + receiverHandle->isHostObject() && "descriptor flags are impossible"); + return vmcast<HostObject>(receiverHandle.get())->set(id, *valueHandle); } }
test/hermes/proxy.js+9 −0 modified@@ -2125,5 +2125,14 @@ checkDeep({...f})(_ => ({a:1, b:2})) // uses fast array access (this will trip an assert otherwise) new Proxy([], {}).unshift(0); +// If putComputed is called on a proxy whose target's prototype is an +// array with a propname of 'length', then internalSetter will be +// true, and the receiver will be a proxy. In that case, proxy needs +// to win; the behavior may assert or be UB otherwise. +var p = new Proxy(Object.create([]), {}); +// using String() forces putComputed +p[String('length')] = 0x123; +p[0xABC] = 1111; + print('done'); // CHECK-LABEL: done
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-x4cf-6jr3-3qvpghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-1915ghsaADVISORY
- github.com/facebook/hermes/commit/8cb935cd3b2321c46aa6b7ed8454d95c75a7fca0ghsax_refsource_CONFIRMWEB
- github.com/facebook/hermes/issues/373ghsaWEB
- www.facebook.com/security/advisories/cve-2020-1915ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.