Skip to content

Commit 78eb904

Browse files
committed
lib: make safe primordials Promise methods
`catch` and `finally` methods on %Promise.prototype% looks up the `then` property of the instance, making it at risk of prototype pollution.
1 parent 7c8a608 commit 78eb904

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

lib/internal/per_context/primordials.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ const {
253253
Map,
254254
ObjectFreeze,
255255
ObjectSetPrototypeOf,
256+
Promise,
257+
PromisePrototypeThen,
256258
Set,
257259
SymbolIterator,
258260
WeakMap,
@@ -384,5 +386,23 @@ primordials.SafeWeakRef = makeSafe(
384386
}
385387
);
386388

389+
const SafePromise = makeSafe(
390+
Promise,
391+
class SafePromise extends Promise {
392+
// eslint-disable-next-line no-useless-constructor
393+
constructor(executor) { super(executor); }
394+
}
395+
);
396+
397+
primordials.PromisePrototypeCatch = (thisPromise, onRejected) =>
398+
PromisePrototypeThen(thisPromise, undefined, onRejected);
399+
400+
primordials.PromisePrototypeFinally = (thisPromise, onFinally) =>
401+
new Promise((a, b) =>
402+
new SafePromise((a, b) => PromisePrototypeThen(thisPromise, a, b))
403+
.finally(onFinally)
404+
.then(a, b)
405+
);
406+
387407
ObjectSetPrototypeOf(primordials, null);
388408
ObjectFreeze(primordials);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Flags: --expose-internals
2+
'use strict';
3+
4+
const common = require('../common');
5+
6+
const {
7+
PromisePrototype,
8+
PromisePrototypeCatch,
9+
PromisePrototypeFinally,
10+
} = require('internal/test/binding').primordials;
11+
12+
PromisePrototype.then = common.mustNotCall();
13+
14+
PromisePrototypeCatch(Promise.reject(), common.mustCall());
15+
PromisePrototypeFinally(Promise.resolve(), common.mustCall());

0 commit comments

Comments
 (0)