GHSA-82jv-9wjw-pqh6 Prototype pollution in emit function

Not scored Published

Prototype pollution in Derby's emit function allows attackers to crash the application via crafted HTML template attributes.

Exploited in the wild
Not known
Login needed
Not needed
Attackable
Over the internet
Victim action needed
Not needed
Fix
Available

What is GHSA-82jv-9wjw-pqh6?

GHSA-82jv-9wjw-pqh6 is a vulnerability in derby, published on 17 Apr 2024. An attacker can exploit it over the internet without logging in, with no action from the victim.

Official description

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);
}

Which versions are affected by GHSA-82jv-9wjw-pqh6?

6 open source packages ship an affected version, including derby.

PackageAffectedFixed in
derby npmAll versions2.3.2
derby npmAll versions2.3.2
derby npmFrom 3.0.03.0.2
derby npmFrom 3.0.03.0.2
derby npmFrom 4.0.0-beta14.0.0-beta.11
derby npmFrom 4.0.0-beta14.0.0-beta.11

How do I fix GHSA-82jv-9wjw-pqh6?

Upgrade derby to a fixed version for your release line: 2.3.2, 3.0.2 or 4.0.0-beta.11.

Is GHSA-82jv-9wjw-pqh6 being exploited?

There is no known exploitation of GHSA-82jv-9wjw-pqh6 in the wild and no public exploit code.

Sources

Is GHSA-82jv-9wjw-pqh6 in your software?

Upload an SBOM and sbomify checks it against every vulnerability here, every day.

Check your SBOMs for free