Egon Okerman d1417e82f8
Modify CWE and OWASP Top 10 links to follow standard link format (APPSEC-1134) (#3529)
* Fix all CWE references

* Fix all OWASP references

* Fix missing CWE prefixes
2024-01-15 17:15:56 +01:00

114 lines
3.2 KiB
Plaintext

Recursively merging objects or dynamically assigning object properties from strings may be prone to Prototype Pollution vulnerabilities in JavaScript. Prototype Pollution vulnerabilities allow to inject new properties into the built-in ``++Object.prototype++`` object. Since most objects inherit from this prototype, it can result in unexpected behavior, e.g., crashes or more severe vulnerabilities.
Recursively merging objects or dynamically assigning object properties from strings has led in the past to the following vulnerabilities:
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10744[CVE-2019-10744]
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11358[CVE-2019-11358]
== Ask Yourself Whether
* Object properties are set dynamically from potential user-input.
There is a risk if you answered yes to any of these questions.
== Recommended Secure Coding Practices
Do not set object properties from user-input. If it cannot be avoided or if you cannot be sure if user-input will be used add an ignore-list to prevent modifications of the following properties:
* ++__proto__++
* constructor
* prototype
== Sensitive Code Example
For merge functions:
----
function for_in_merge(dst, src) {
for (let key in src) {
if (dst[key]) {
for_in_merge(dst[key], src[key]);
} else {
dst[key] = src[key]; // Sensitive
}
}
}
----
For set-path functions:
----
function for_set(target, path, value) {
let keys = path.split('.');
for (let i = 0; i < keys.length; ++i) {
let key = keys[i];
if (i < keys.length - 1) {
if (!target[key]) {
target[key] = {};
}
target = target[key];
} else {
target[key] = value; // Sensitive
}
}
}
----
== Compliant Solution
For merge functions:
[source,javascript]
----
function for_in_merge(dst, src) {
for (let key in src) {
// Recommended Secure Coding Practices: prevent sensible keys
if (key === "constructor" || key === "prototype" || key === "__proto__") {
continue;
}
if (dst[key]) {
for_in_merge(dst[key], src[key]);
} else {
dst[key] = src[key]; // Compliant
}
}
}
----
For set-path functions:
[source,javascript]
----
function for_set(target, path, value) {
let keys = path.split('.');
for (let i = 0; i < keys.length; ++i) {
let key = keys[i];
// Recommended Secure Coding Practices: prevent sensible keys
if (key === "constructor" || key === "prototype" || key === "__proto__") {
break;
}
if (i < keys.length - 1) {
if (!target[key]) {
target[key] = {};
}
target = target[key];
} else {
target[key] = value; // Compliant
}
}
}
----
== See
* https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf[Prototype pollution attack in NodeJS application - Olivier Arteau]
* CWE - https://cwe.mitre.org/data/definitions/1321[CWE-1321 - Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')]