TOCTTOU issue in Proxy invariant checks
# Mark S. Miller (11 years ago)
your reasoning seems good to me.
Hi Tom, your reasoning seems good to me. On Jul 21, 2014 11:27 PM, "Tom Van Cutsem" <tomvc.be at gmail.com> wrote: > Hi, > > While reviewing some changes to the Proxy spec in the latest revision, it > occurred to me there is a potential time-of-check-to-time-of-use (TOCTTOU) > issue in the Proxy invariant checks. > > Concretely, take revision 26, section 9.5.12 [[OwnPropertyKeys]]: > - step 11 checks whether the target object is extensible > - this result then gets used in step 21 and 28 (if the target was > non-extensible, more invariant checks are made) > - in between steps 11 and 21/28, control is transferred to internal > methods of the target, which may itself be a Proxy and so trigger arbitrary > user code to run. > - hence, the extensibility state checked in step 11 might have changed > before being used in steps 21/28 > > I think the issue is benign, because extensibility can only ever change > from 'true' to 'false' but not vice versa. This means we can end up in the > following scenario: > > - assume a proxy and its target are extensible when [[OwnPropertyKeys]] is > invoked > - step 11 checks the extensibility state and stores 'true' > - assume user code runs between steps 11 and 21 that calls > Object.preventExtensions on the target, so the extensibility state is now > really 'false' > - Then, in step 21, even though the target is now non-extensible, the > algorithm terminates early and doesn't perform the invariant checks for > non-extensible objects. > > I think this is benign because the caller of the internal method, at the > time it made the call, had no reason to assume strong invariants on the > proxy/target. > > Basically, the way to think of this is that invariant checks are made > based upon the state of the target object when the internal method is first > invoked. While that internal method call is suspended, the target's state > may change, but invariant checks may still be based on the target's state > upon entry. > > While I'm fairly confident the issue is benign, the reasoning is subtle > and could use more braincells to check if I missed anything. > > This issue may appear for other Proxy internal methods, I haven't yet > checked. But generally I think they will also be benign for the same > reasons. An attacker can only modify the target to have stronger, not > weaker, invariants. Suspended calls that only assume weak invariants cannot > get confused if eventually more invariant checks are made. > > Cheers, > Tom > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140722/53cc0370/attachment.html>
While reviewing some changes to the Proxy spec in the latest revision, it occurred to me there is a potential time-of-check-to-time-of-use (TOCTTOU) issue in the Proxy invariant checks.
Concretely, take revision 26, section 9.5.12 [[OwnPropertyKeys]]:
I think the issue is benign, because extensibility can only ever change from 'true' to 'false' but not vice versa. This means we can end up in the following scenario:
I think this is benign because the caller of the internal method, at the time it made the call, had no reason to assume strong invariants on the proxy/target.
Basically, the way to think of this is that invariant checks are made based upon the state of the target object when the internal method is first invoked. While that internal method call is suspended, the target's state may change, but invariant checks may still be based on the target's state upon entry.
While I'm fairly confident the issue is benign, the reasoning is subtle and could use more braincells to check if I missed anything.
This issue may appear for other Proxy internal methods, I haven't yet checked. But generally I think they will also be benign for the same reasons. An attacker can only modify the target to have stronger, not weaker, invariants. Suspended calls that only assume weak invariants cannot get confused if eventually more invariant checks are made.