-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: make Promise.resolve safe. #1126
Conversation
Co-authored-by: Richard Gibson <richard.gibson@gmail.com>
Right I was gonna say all the attacker needs to do is restore the original constructor as an own property. The only way the attacker wouldn't be able to attack this is if the original constructor was never exposed to the user code, aka that the global |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know enough about the mechanics to comment other than to ask: why not install a SES-specific wrapper as Promise.resolve
?
That would work for explicit calls to |
@mhofman states exactly why I was interested. But at least for the implicit We need to look at all the other places in the spec that call the internal |
@mhofman , I did not understand
I don't think either part is true, but I may be misunderstanding your point. |
Changing Wondering what the test262 coverage is on all those behaviors. |
Actually this may be fine.
So TL;DR, I think the only unexcepted case may be |
Let me try to think about this again, in context of the above existing defenses in
There are 3 approaches we can take:
The first approach as stated a few comments above can be defeated by the attacker adding an own The second approach would cause the "implicit resolve" invocations of The third approach might actually be sufficient since The remaining question is the auto freeze for "implicit resolve" cases like |
If it provided a useful guarantee, then we might care. But I don't think it does. It is at best a useful diagnostic to catch a certain kind of accident. With this diagnostic on, I was very pleased that we were green without needing to fix anything! |
Closing as a failed experiment |
Can we open an issue to investigate patching |
Yes, please do! I'd be happy to review. Thanks ;) |
My original intention on tc39 was that an expression like
protect the code it appears in from reentrancy attacks no matter what
p
is. IOW, even ifp
andwhatever
are provided by an adversary, that adversary should not be able to get of their choosing to run within the caller's turn. However, this was attackable by installing athen
function` as an own property on a genuine promise.Recently I learned that
Promise.resolve
does more than simply coercep
to a genuine promise. It also checks thatp.constructor === Promise
. This PR experiments with makingPromise.prototype.constructor
into an accessor function whose getter ensures the rest is safe.This PR is currently a draft because, after I got it "working" I realized there is a remaining vulnerability: The adversary can install an own
constructor
property onp
, overriding the protective accessor. This flaw may be fatal for this approach.Stacked on #1115