1 of 12

Proposal: Curtailing the power of "Thenables"

Matthew Gaudet, Mozilla

2 of 12

Reminder: What are Thenables

  • Objects with then property are “thenables”, and treated specially in Promise code
  • Why? For compatibility with pre-standard promise libraries

3 of 12

What’s the problem here?

Basically: It is easy for implementers of web-specifications, engines and specification writers to forget that this behaviour exists, and accidentally introduce user-controlled execution in places it wasn’t expected:

For example: calling Promise.resolve on a newly created WebIDL dictionary type?

Seems safe?

Oops. Dictionaries convert to objects with [[Prototype]] set to Object.prototype – accidental user code execution

4 of 12

What’s the problem here?

Result: CVE after CVE

  • CVE-2024-43357 on the specification.
  • Out of bound access in ReadableStream::Close
  • CVE-2021-21206: Chrome Use-After-Free in Animations
  • CVE-2024-9086
  • And more – frankly, I didn’t look that hard.

5 of 12

Stage 0 to 1 Ask: Can we do anything here?

6 of 12

During remediation of CVE-2024-43357 (The Spec CVE) a couple fixes were proposed that helped here:

  1. Make Object.prototype exotically reject "then" properties. Change the [[DefineOwnProperty]] MOP operation on Object.prototype to silently no-op when the property key is "then".
  2. Make some promise resolve functions not respect thenables. Exclude certain internal resolution functions to not respect thenables.

7 of 12

A Possible Third Path

I would propose a third solution:

  • Specification defined prototypes gain a new internal slot [[InternalProto]]
  • The lookup for the then property changes from Get to GetNonInternal, a new specification AO which walks the prototype chain, but stops as soon as it encounters a prototype with the [[InternalProto]] internal slot.

8 of 12

Some Advantages

  1. In my opinion a more harmonious design
  2. Can be integrated into WebIDL – Change WebIDL spec to make IDL defined prototypes [[InternalProto]]
  3. Avoids making Object.prototype exotic

9 of 12

Does this solve everything?

Nope. This is a mitigation, an attempt to make easy-to-make errors safer. It does not address the whole class of “thenable” problems.

10 of 12

Compatibility

In preparation for this proposal I added some telemetry to Firefox to see what roughly we could expect as far as problems go.

Date

Thenable %

Thenable on Proto %

Thenable on Standard Proto %

2025-02-04

2.27

2.00

0.13

2025-02-03

2.31

2.04

0.12

2025-02-02

2.39

2.12

0.11

2025-02-01

2.25

2.00

0.12

11 of 12

Other solutions welcome!

Stage 0 to 1 isn’t about “I have a solution”, it’s about problem identification.

I’m interested in more discussion, other solutions etc.

12 of 12

Stage 1?