-
Notifications
You must be signed in to change notification settings - Fork 78
Description
@danfinlay raises an issue we have struggled with: it’s currently not possible to terminate CapTP in a realm that does not also use the SES shim, because these layers depend upon harden
. We have yet to find a nice compromise that allows us to write these libraries in a way that works well in both hardened and unhardened JavaScript without compromising the readability or audit-ability of that code in the hardened case. Some of the difficulty lies in the dichotomy:
harden
walks up prototype chains, so hardening an object before lockdown would cause the repair phase to throw errorsharden
that does not walk up the prototype chain does not provide assurance that the object is transitively hardened
However, it is clearly the responsibility of the creator of instances to harden the instance and also clearly the responsibility of a library to harden its classes, constructors, prototypes, return values, and so on. Currently, harden
does both as a safeguard against a library that failed to harden itself.
So, I propose we can break this logjam with the following strategy:
- We recreate an
@endo/harden
user-space implementation ofharden
that is a ponyfill forglobalThis.harden
and otherwise provides an implementation that freeze an object by walking transitive properties and not prototype chains. This is a version ofharden
that is suitable for use in both unhardened JavaScript and hardened JavaScript. - We also change
globalThis.harden
so that it freezes exactly the same objects as the ponyfill, and asserts that every hardened object is transitively frozen over both property and prototype, throwing an error that indicates that the hardened instance must stand on top of only hardened prototypes.
This would allow us to refactor CapTP and all its dependencies to depend on the @endo/harden
ponyfill, making CapTP usable without shims, equally safe with shims, and otherwise identical verbatim to the current implementation.