Closed michaelfig closed 1 year ago
We will wait on this change until @erights is available for further discussion.
Note for attribution if/when you merge it: I've changed my @ from @isiahmeadows to @dead-claudia. Just thought I'd let you all know. 🙂
@erights Not quite. It would be a fresh object if and only if the user provides a fresh object, stemming from the fact the method would treat it semantically as an opaque value. Concretely, it's really only changing the syntax for creation to reduce its surface area:
// Old
return new Promise.delegated((resolve, reject, resolveWithPresence) => {
const presence = resolveWithPresence(getHandler())
initializePresence(presence)
})
// This PR
const presence = Object.create(null)
const delegated = Promise.delegated.resolveWithPresence(presence, getHandler())
initializePresence(presence)
return delegated
If I'm understanding the proposal correctly, the core security component comes not from uniqueness or "freshness" of the presence, but from encapsulation of the handler.
Feel free to correct me if I'm wrong.
Hi @dead-claudia the scenario I'm concerned with is where, say, Alice, creates a defensive object foo
that she gives to Bob. Alice and Bob are mutually suspicious. Bob, with Alice's foo
object, does
const delegated = Promise.delegated.resolveWithPresence(foo, getHandler());
Alice has also shared her foo
object with Carol. Carol does, for example,
E(foo).bar();
Had Bob not done anything, this would be handled by foo.bar()
. However, because of Bob's action, it is handled according to the handler Bob attached to it, subverting Alice's intentions.
The freshness guarantee prevents this. The presence cannot have been someone else's object.
Hi @dead-claudia the scenario I'm concerned with is where, say, Alice, creates a defensive object
foo
that she gives to Bob. Alice and Bob are mutually suspicious. Bob, with Alice'sfoo
object, doesconst delegated = Promise.delegated.resolveWithPresence(foo, getHandler());
Alice has also shared her
foo
object with Carol. Carol does, for example,E(foo).bar();
Had Bob not done anything, this would be handled by
foo.bar()
. However, because of Bob's action, it is handled according to the handler Bob attached to it, subverting Alice's intentions.The freshness guarantee prevents this. The presence cannot have been someone else's object.
Already tried to addressed it, though apparently I left way too much implied: (emphasis added)
- The presence is more or less just an early return value, and carries the same security concerns as a promise resolution value. If freshness and invisibility of the host prototype chain is a requirement for presences (say, it's code providing a service to multiple distrusted scripts), it'll also be a requirement for general return values, so there isn't any new untrodden ground here. It just means the same concern has to be addressed in two separate places. (It's not like this concern doesn't already exist for properties set to objects and functions - the attack surface area was already there.)
The intended implication here is that Alice, as she is suspicious of Bob, already would have to harden (read: replace prototype then optionally Object.freeze
) any property she adds to her presence anyways. The only difference is she now has to harden the presence itself in full instead of just the assigned foo.bar
on the presence.
Alice already has to know how to harden objects as she passes them to Bob and (presumably also) Carol to avoid exposing her own realm's prototypes, so it's only an extra step to harden the immediate object sent and not just the method.
I'm also looking at non-security-critical uses of this proposal, cases that simply leverage the eventual send functionality for incremental network communication but only have one trusted actor rather than several mutually suspicious actors.
BTW, I'd recommend you all take a look at https://github.com/tc39/proposal-eventual-send/issues/31 and tell me what you think.
opts
parameter, as you can already get 90% of the way there by either plumbing settings through the proxies and/or accepting settings as an extra parameter.And of course, in an effort to keep the "send" part of the eventual send in, I'm pumping up the absolute historical lead balloon of a method call proxy trap, attempting to also use other use cases to further justify its inclusion.
I'm closing this PR because, while we didn't come to consensus on the freshness requirement for presences, I believe #31 is a much better foundation and bypasses the issue by not having a special category of presences at all.
Closes: #22
Taking advice from @dead-claudia in #22, I'm proposing this revamp of the spec to improve its clarity and only introduce the
Promise.delegated
namespace for all the API additions.