CVE-2026-118777: Prototype Pollution in Forge HTTP Client Cookie Management
Vulnerability ID: CVE-2026-118777
CVSS Score: 4.8
Published: 2026-10-30
CVE-2026-118777 is a prototype pollution vulnerability (CWE-1321) in the Forge JavaScript cryptography and networking library (distributed on npm as node-forge) prior to version 1.4.1. The flaw resides in the forge.http client subsystem, where incoming HTTP cookie names and paths parsed from Set-Cookie response headers are stored directly into standard JavaScript objects without key validation or property isolation. By returning crafted Set-Cookie headers containing keys such as proto or constructor, a malicious HTTP server can inject arbitrary properties into Object.prototype, attach attributes to the global Object constructor, or delete built-in prototype methods to cause an application-wide denial of service.
TL;DR
Forge (node-forge) versions prior to 1.4.1 are vulnerable to prototype pollution and arbitrary prototype property deletion in the forge.http client when processing crafted Set-Cookie HTTP response headers from untrusted servers. Upgrading to version 1.4.1 resolves the issue.
⚠️ Exploit Status: POC
Technical Details
- Vulnerability Type: Prototype Pollution (CWE-1321)
- Affected Component: forge.http / lib/http.js (node-forge < 1.4.1)
- Attack Vector: Network (Malicious HTTP Set-Cookie Response Header)
- CVSS v3.1 Score: 4.8 Medium (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L)
- EPSS Score: 0.26% (17.16th Percentile)
- Impact: Object.prototype Mutation & Denial of Service via Method Deletion
- Exploit Status: PoC (Regression Tests in Repository)
- CISA KEV Status: Not Listed
Affected Systems
- node-forge (npm package)
- forge JavaScript library (forge.http, forge.xhr, and forge.all browser bundle)
-
node-forge: < 1.4.1 (Fixed in:
1.4.1)
Code Analysis
Commit: 797c3f8
Prevent Object.prototype and Object modification via Set-Cookie headers in forge.http.
diff --git a/lib/http.js b/lib/http.js
index fe52986b1..b94f99682 100644
--- a/lib/http.js
+++ b/lib/http.js
@@ -21,6 +21,19 @@ var _normalize = function(name) {
function(a) {return a.toUpperCase();});
};
+/**
+ * Checks for an own property, so cookie names and paths from a server can't
+ * reach properties inherited from Object.prototype.
+ *
+ * @param obj the object.
+ * @param key the property name.
+ *
+ * @return true if obj has its own property key.
+ */
+var _hasOwn = function(obj, key) {
+ return Object.prototype.hasOwnProperty.call(obj, key);
+};
+
/**
* Gets the local storage ID for the given client.
*
@@ -689,8 +702,13 @@ http.createClient = function(options) {
throw error;
}
+ // '__proto__' can't be stored as a plain object key
+ if(cookie.name === '__proto__' || cookie.path === '__proto__') {
+ return false;
+ }
+
// add new cookie
- if(!(cookie.name in client.cookies)) {
+ if(!_hasOwn(client.cookies, cookie.name)) {
client.cookies[cookie.name] = {};
}
client.cookies[cookie.name][cookie.path] = cookie;
@@ -715,12 +733,12 @@ http.createClient = function(options) {
*/
client.getCookie = function(name, path) {
var rval = null;
- if(name in client.cookies) {
+ if(_hasOwn(client.cookies, name)) {
var paths = client.cookies[name];
// get path-specific cookie
if(path) {
- if(path in paths) {
+ if(_hasOwn(paths, path)) {
rval = paths[path];
}
} else {
@@ -745,11 +763,11 @@ http.createClient = function(options) {
*/
client.removeCookie = function(name, path) {
var rval = false;
- if(name in client.cookies) {
+ if(_hasOwn(client.cookies, name)) {
// delete the specific path
if(path) {
var paths = client.cookies[name];
- if(path in paths) {
+ if(_hasOwn(paths, path)) {
rval = true;
delete client.cookies[name][path];
// clean up entry if empty
Exploit Details
- GitHub: Official security regression test suite (tests/security/ghsa-6wvx-3r32-xmcg.js) demonstrating prototype pollution and property deletion via Set-Cookie headers.
Mitigation Strategies
- Upgrade node-forge to version 1.4.1 or later to enforce own-property checks and block 'proto' keys in cookie storage.
- Eliminate unused attack surface by avoiding the monolithic 'forge.all' bundle when only cryptographic primitives are required.
- Enforce runtime prototype immutability via Object.freeze(Object.prototype) or the Node.js --disable-proto=throw CLI flag where compatible.
- Restrict forge.http outbound connections to trusted endpoints and strip malformed Set-Cookie headers containing 'proto' or 'constructor' at network egress proxies.
Remediation Steps:
- Check the installed version of node-forge using 'npm list node-forge' or 'yarn why node-forge'.
- Update package.json to specify '"node-forge": "^1.4.1"' and run 'npm install' or 'yarn install'.
- If using custom webpack/rollup browser bundles, rebuild and redeploy client assets so that lib/http.js includes the v1.4.1 patch.
- Verify the fix by running the application's test suite and confirming node-forge resolves to 1.4.1 in package-lock.json or yarn.lock.
References
- GitHub Security Advisory: GHSA-6wvx-3r32-xmcg
- Fix Commit 797c3f816a22748a96fceebb34eb3a6716853991 in digitalbazaar/forge
- Forge Release v1.4.1
- Official CVE Record: CVE-2026-118777
- NVD Vulnerability Detail: CVE-2026-118777
- CVE List V5 JSON Record: CVE-2026-118777
- Wiz Vulnerability Database: CVE-2026-118777
Read the full report for CVE-2026-118777 on our website for more details including interactive diagrams and full exploit analysis.
Top comments (0)