GHSA-82jv-9wjw-pqh6: Derby Prototype Pollution Vulnerability
LOWGHSA-82jv-9wjw-pqh6 is a LOW prototype pollution vulnerability (CWE-1321: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')) affecting Derby libraries in the npm ecosystem. The issue involves prototype pollution in emit function. Remediation is available by upgrading affected packages to version 2.3.2, 3.0.2, 4.0.0-beta.11.
GHSA-82jv-9wjw-pqh6 at a Glance
How to Fix GHSA-82jv-9wjw-pqh6
To remediate this vulnerability, upgrade all affected Derby dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
npm install derby@2.3.2
npm install derby@3.0.2
npm install derby@4.0.0-beta.11
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
npm ls derby
How to Check if You Are Affected
To determine whether your Node.js application is affected by GHSA-82jv-9wjw-pqh6, inspect your project dependencies using npm:
npm ls derby
Analyze the terminal output to locate any version of Derby in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.3.2), your application is affected.
Note: The npm ls derby command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-1321: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution'), where the product receives input from an upstream component that specifies attributes that are to be initialized or updated in an object, but it does not properly control modifications of attributes of the object prototype. In Derby, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
GHSA-82jv-9wjw-pqh6 Affected Derby Versions
3 component(s)References
Frequently Asked Questions
What is GHSA-82jv-9wjw-pqh6?
Which Derby versions are affected?
What version fixes GHSA-82jv-9wjw-pqh6?
Is derby affected?
What CWE is associated with GHSA-82jv-9wjw-pqh6?
How can I check npm dependencies for GHSA-82jv-9wjw-pqh6?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-82jv-9wjw-pqh6",
"modified" : "2024-04-17T22:26:37Z",
"published" : "2024-04-17T22:26:37Z",
"aliases" : [ ],
"summary" : "Prototype pollution in emit function",
"details" : "### Summary\nA prototype pollution in derby can crash the application, if the application author has atypical HTML templates that feed user input into an object key.\n\nAttribute keys are almost always developer-controlled, not end-user-controlled, so this shouldn't be an issue in practice for most applications.\n\n### Details\n```\nemit(context: Context, target: T) {\n const node = traverseAndCreate(context.controller, this.segments);\n node[this.lastSegment] = target;\n this.addListeners(target, node, this.lastSegment);\n}\n```\nThe emit() function in src/templates/templates.ts is called without sanitizing the variable `this.lastSegment `. The variable `this.lastSegment ` can be set to `__proto__`, and this will pollute the prototype of Javascipt Object (`node['__proto__'] = target`).\n\n### PoC\nTo reproduce this vulnerability, you can adjust the test case `ignores DOM mutations in components\\' create()` in `test/dom/ComponentHarness.mocha.js`.\n\n```\nit('ignores DOM mutations in components\\' create()', function() {\n function Box() {}\n Box.view = {\n is: 'box',\n- source: '<index:><div class=\"box\" as=\"boxElement\"></div>'\n+ source: '<index:><div class=\"box\" as=\"__proto__\"></div>'\n };\n Box.prototype.create = function() {\n this.boxElement.className = 'box-changed-in-create';\n };\n var harness = runner.createHarness('<view is=\"box\" />', Box);\n expect(harness).to.render('<div class=\"box\"></div>');\n});\n```\nWhen `as` attribute is controlled by attackers, the variable in `this.lastSegment` will exactly take value` __proto__` and prototype pollution happens.\n\n### Patch\nAdd a check on `this.lastSegment` can prevent this attack.\n```\nemit(context: Context, target: T) {\n const node = traverseAndCreate(context.controller, this.segments);\n+ if (this.lastSegment.includes('__proto__') || this.lastSegment.includes('prototype')) {\n+ throw new Error('Unsafe code detected');\n+ }\n node[this.lastSegment] = target;\n this.addListeners(target, node, this.lastSegment);\n}\n```\n",
"severity" : [ ],
"affected" : [ {
"package" : {
"ecosystem" : "npm",
"name" : "derby"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "2.3.2"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 2.3.1"
}
}, {
"package" : {
"ecosystem" : "npm",
"name" : "derby"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "3.0.0"
}, {
"fixed" : "3.0.2"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 3.0.1"
}
}, {
"package" : {
"ecosystem" : "npm",
"name" : "derby"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "4.0.0-beta1"
}, {
"fixed" : "4.0.0-beta.11"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 4.0.0-beta.10"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/derbyjs/derby/security/advisories/GHSA-82jv-9wjw-pqh6"
}, {
"type" : "WEB",
"url" : "https://github.com/derbyjs/derby/commit/24524e96f36976883c7c619811320428536bd4d0"
}, {
"type" : "WEB",
"url" : "https://github.com/derbyjs/derby/commit/465a0c2f6a77361eda4a09b77a8c94ba6a9da440"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/derbyjs/derby"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-1321" ],
"severity" : "LOW",
"github_reviewed" : true,
"github_reviewed_at" : "2024-04-17T22:26:37Z",
"nvd_published_at" : null
}
}