GHSA-82JV-9WJW-PQH6

Vulnerability from github – Published: 2024-04-17 22:26 – Updated: 2024-04-17 22:26
VLAI
Summary
Prototype pollution in emit function
Details

Summary

A prototype pollution in derby can crash the application, if the application author has atypical HTML templates that feed user input into an object key.

Attribute keys are almost always developer-controlled, not end-user-controlled, so this shouldn't be an issue in practice for most applications.

Details

emit(context: Context, target: T) {
  const node = traverseAndCreate(context.controller, this.segments);
    node[this.lastSegment] = target;
    this.addListeners(target, node, this.lastSegment);
}

The 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).

PoC

To reproduce this vulnerability, you can adjust the test case ignores DOM mutations in components\' create() in test/dom/ComponentHarness.mocha.js.

it('ignores DOM mutations in components\' create()', function() {
      function Box() {}
      Box.view = {
        is: 'box',
-        source: '<index:><div class="box" as="boxElement"></div>'
+        source: '<index:><div class="box" as="__proto__"></div>'
      };
      Box.prototype.create = function() {
        this.boxElement.className = 'box-changed-in-create';
      };
      var harness = runner.createHarness('<view is="box" />', Box);
      expect(harness).to.render('<div class="box"></div>');
});

When as attribute is controlled by attackers, the variable in this.lastSegment will exactly take value__proto__ and prototype pollution happens.

Patch

Add a check on this.lastSegment can prevent this attack.

emit(context: Context, target: T) {
  const node = traverseAndCreate(context.controller, this.segments);
+  if (this.lastSegment.includes('__proto__') || this.lastSegment.includes('prototype')) {
+    throw new Error('Unsafe code detected');
+  }
    node[this.lastSegment] = target;
    this.addListeners(target, node, this.lastSegment);
}
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2.3.1"
      },
      "package": {
        "ecosystem": "npm",
        "name": "derby"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.3.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.0.1"
      },
      "package": {
        "ecosystem": "npm",
        "name": "derby"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.0.0"
            },
            {
              "fixed": "3.0.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.0.0-beta.10"
      },
      "package": {
        "ecosystem": "npm",
        "name": "derby"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.0.0-beta1"
            },
            {
              "fixed": "4.0.0-beta.11"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-04-17T22:26:37Z",
    "nvd_published_at": null,
    "severity": "LOW"
  },
  "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\u0027t 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[\u0027__proto__\u0027] = target`).\n\n### PoC\nTo reproduce this vulnerability, you can adjust the test case `ignores DOM mutations in components\\\u0027 create()` in `test/dom/ComponentHarness.mocha.js`.\n\n```\nit(\u0027ignores DOM mutations in components\\\u0027 create()\u0027, function() {\n      function Box() {}\n      Box.view = {\n        is: \u0027box\u0027,\n-        source: \u0027\u003cindex:\u003e\u003cdiv class=\"box\" as=\"boxElement\"\u003e\u003c/div\u003e\u0027\n+        source: \u0027\u003cindex:\u003e\u003cdiv class=\"box\" as=\"__proto__\"\u003e\u003c/div\u003e\u0027\n      };\n      Box.prototype.create = function() {\n        this.boxElement.className = \u0027box-changed-in-create\u0027;\n      };\n      var harness = runner.createHarness(\u0027\u003cview is=\"box\" /\u003e\u0027, Box);\n      expect(harness).to.render(\u0027\u003cdiv class=\"box\"\u003e\u003c/div\u003e\u0027);\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(\u0027__proto__\u0027) || this.lastSegment.includes(\u0027prototype\u0027)) {\n+    throw new Error(\u0027Unsafe code detected\u0027);\n+  }\n    node[this.lastSegment] = target;\n    this.addListeners(target, node, this.lastSegment);\n}\n```\n",
  "id": "GHSA-82jv-9wjw-pqh6",
  "modified": "2024-04-17T22:26:37Z",
  "published": "2024-04-17T22:26:37Z",
  "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"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [],
  "summary": "Prototype pollution in emit function"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…