Re: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On 9 November 2011 00:16, Mark S. Miller erig...@google.com wrote: On Tue, Nov 8, 2011 at 12:50 PM, Andreas Rossberg rossb...@google.com wrote: On 8 November 2011 20:46, Mark S. Miller erig...@google.com wrote: Nevertheless, I see your point. Many defensive ES5 abstractions will be less defensive than this. If I understand you correctly, your point is specifically about the [[Call]] and [[Construct]] traps. Yes. Existing code has no reason to bother making functions non-extensible if all it does is calling them. Proxy.attach fundamentally breaks that (so far correct, AFAICT) assumption. I think we're agreeing on the operational point -- that much defensive code won't bother to freeze such functions. But for clarity, I must correct your no reason. The reason is one of the oldest software engineering best practices: Say What You Mean. Perhaps a clearer statement is Mean Only What You Say. The it in your above sentence presumes a non-local whole program analysis which violates this rule, and is in any case inapplicable to libraries. To keep what the program means in sync with what it seems to mean, we need to avoid introducing unexpressed communication channels. Or, put another way, unexpressed shared mutable locations. If Alice provides object C to both B and D, the only ways in which this should enable further communication between B and D (beyond that which they may have already had) should be according to the expressed behavior of C. For example, if the expressed behavior of C is completely stateless, then the fact that B and D both share a reference to C should not enable any additional communications/interaction/influence between B and D. These constraints are useful for much beyond security. If you wish to program in a mostly functional style, you'd like the deviations from functional style to only be where you've made a purposeful choice. When debugging, you need to figure out: How did the bad symptom happen? If you can bound the possible causes, by reasoning in terms of the program's intended behavior, your detective work is much easier. Agreed with everything you say. But I suppose there are two levels of concern: protecting your own abstractions, and not providing security loopholes that others can exploit to harm third parties. Given how hostile JS is towards encouraging the latter, I would expect that a significant amount of code exists that only cares about the former, which I think is a valid concern on its own. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On Tue, Nov 8, 2011 at 4:58 PM, Tom Van Cutsem tomvc...@gmail.com wrote: Perhaps we should be more conservative here, without necessarily backing away from the whole Proxy.attach idea? Disallowing attaching to functions with your own call/construct traps would be the minimal restriction, I think. But maybe there is something cleaner. I wonder if chaperones, as implemented in Racket, would be of help here. To my understanding, a chaperone is a proxy that is very restricted in its actions, specifically: when intercepting a function call, a chaperone is only allowed to throw an exception, return the original value, or a chaperone for the original value (racketeers on this list should correct me where needed). Chaperones would still be powerful enough to express data binding: firing an update event as a side-effect does not require changing the arguments or return values of wrapped functions. However, at this point I'm not yet sufficiently familiar with chaperones to see how they can be adapted into our Proxy framework. That's a very accurate summary. I agree with Andreas that this is a significant risk for Proxy.attach. ES in the wild has few enough invariants that we should be very wary of breaking the ones we've got. However, the direct proxy proposal is already enforcing some invariants -- the proxy must produce === values to the underlying object for frozen properties. Could we just reuse this mechanism for the [[Call]] and [[Construct]] behavior of functions in the cases Andreas brings up for Proxy.attach (if we decide that we want it)? The idea of chaperones would be then relaxing this invariant slightly, to allow frozen properties to produce proxies for the underlying property value, instead of just something === to it. This makes proxies more expressive in some cases, without reducing the invariants we can rely on. -- sam th sa...@ccs.neu.edu ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
Le 08/11/2011 14:26, Andreas Rossberg a écrit : On 3 November 2011 23:55, Mark S. Miller erig...@google.com wrote: If I understood Mark correctly, the features needed for SES are already part of ES.5 and are shipping in browsers (and hence don't bear upon future features). Did I misunderstand? These do bear on future features in three ways: 1) Future features could easily destroy all the security gains that ES5 achieved. I'm still trying to grasp the implications of the recent direct proxy proposal in this respect -- more precisely, its startTrapping functionality. Just as a reminder, startTrapping really is not necessary to direct proxies (Proxy.for) and should both should be considered independently (even though they are on the same strawman) It seems to me that the ability to attach to a function, in particular, invalidates all current security guarantees, since it gives a whole new way of completely redefining any random function _in place_ by simply turning it into a function proxy. That is, even if that function is given by a non-writable binding or property! Given that direct proxies are not in a position to violate any of the *non-configurability or non-extensibility constraints* of their wrapped target, it should be safe to replace an existing normal object by a direct proxy wrapping that object. My understanding is that regarding the issue you mention, you cannot do more with startTrapping than redefining built-ins by (re)setting a property. Though, I agree about the non-writable binding. Something should be added about that. And it seems so much safer to prevent start trapping the global object because things could get nasty otherwise. To achieve the effect of today's Object.{seal,freeze}, you hence also would have to make _every_ of the object's properties non-attachable. That is certainly possible, but seems considerably more fragile.And it still breaks the security of pre-existing SES code. IOW, I sense a security hazard. I agree that there is a hazard but I am not sure it is that much bigger than the opportunity for an attacker to redefine built-ins. This opportunity exists since the origin of JavaScript (so before ES5 and SES). I also wonder about the effect that turning an (ordinary) object into a proxy would have on the visibility of private names. If one of the original methods accesses a private property on `this', then, according to the private names proposal, the handler only gets to see the .public property of that name. But can't this still leak information? The handler cannot use it to _read_ the existing property data, but it will still receive all future _writes_ to it. Am I missing something? I don't think you are. I think you are right. As said, the startTrapping proposal is controversial. Proxies are still very new. I'm not sure it's wise to add the startTrapping. If we ever realize that this is really needed, i don't think there is a problem with adding it in a later ECMAScript version. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On Tue, Nov 8, 2011 at 5:26 AM, Andreas Rossberg rossb...@google.comwrote: On 3 November 2011 23:55, Mark S. Miller erig...@google.com wrote: If I understood Mark correctly, the features needed for SES are already part of ES.5 and are shipping in browsers (and hence don't bear upon future features). Did I misunderstand? These do bear on future features in three ways: 1) Future features could easily destroy all the security gains that ES5 achieved. I'm still trying to grasp the implications of the recent direct proxy proposal in this respect -- more precisely, its startTrapping functionality. It seems to me that the ability to attach to a function, in particular, invalidates all current security guarantees, since it gives a whole new way of completely redefining any random function _in place_ by simply turning it into a function proxy. That is, even if that function is given by a non-writable binding or property! To achieve the effect of today's Object.{seal,freeze}, you hence also would have to make _every_ of the object's properties non-attachable. That is certainly possible, but seems considerably more fragile. And it still breaks the security of pre-existing SES code. IOW, I sense a security hazard. Hi Andreas, thanks for starting a discussion on this. I agree that there is a huge danger here. There is another approach to so-called data binding (treat it like an optimization of polling) that cannot cause any loss of security (if equivalence to polling really is maintained). Altogether, from a security pov, we'd certainly be better off without Proxy.attach. The reason Proxy.attach may not be fatal is that it only allows attachment to extensible objects. Our hypothesis is that any ES5 object that is interested in defending itself has already made itself non-extensible. This is why we must key this off of non-extensibility, rather than introducing a new orthogonal bit -- to avoid breaching the defenses of those ES5 era objects that tried to defend themselves. ES3 era objects could not defend themselves, so attaching to them cannot violate any of their valid assumptions -- to a first approximation, they could not validly assume anything. I also wonder about the effect that turning an (ordinary) object into a proxy would have on the visibility of private names. If one of the original methods accesses a private property on `this', then, according to the private names proposal, the handler only gets to see the .public property of that name. But can't this still leak information? The handler cannot use it to _read_ the existing property data, but it will still receive all future _writes_ to it. Am I missing something? Only the defensiveness points above. Regarding data binding, we should also see if the non-dangerous poll-optimization-equivalence can meet our needs instead, in which case we probably don't need Proxy.attach. /Andreas -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On 8 November 2011 18:47, David Bruant bruan...@gmail.com wrote: Given that direct proxies are not in a position to violate any of the *non-configurability or non-extensibility constraints* of their wrapped target, it should be safe to replace an existing normal object by a direct proxy wrapping that object. My understanding is that regarding the issue you mention, you cannot do more with startTrapping than redefining built-ins by (re)setting a property. That may be true for plain objects, but I think the situation is quite different for functions, because there is no equivalent to non-configurable for the [[Call]] and [[Construct]] properties. On 8 November 2011 19:13, Mark S. Miller erig...@google.com wrote: The reason Proxy.attach may not be fatal is that it only allows attachment to extensible objects. Our hypothesis is that any ES5 object that is interested in defending itself has already made itself non-extensible. This is why we must key this off of non-extensibility, rather than introducing a new orthogonal bit -- to avoid breaching the defenses of those ES5 era objects that tried to defend themselves. I don't think that addresses the issue I was describing. The problem is: the object itself can all be frozen, non-extensible, non-attachable just fine, but that doesn't achieve much by itself anymore because an attacker can still attach to each individual method, since they are entirely separate objects! So instead of just freezing an object, you _additionally_ would have to make all its _individual methods_ non-attachable (by whatever means). AFAICS, that affects assumptions of existing ES5 code quite severely. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On 8 November 2011 20:29, Andreas Rossberg rossb...@google.com wrote: On 8 November 2011 18:47, David Bruant bruan...@gmail.com wrote: Given that direct proxies are not in a position to violate any of the *non-configurability or non-extensibility constraints* of their wrapped target, it should be safe to replace an existing normal object by a direct proxy wrapping that object. My understanding is that regarding the issue you mention, you cannot do more with startTrapping than redefining built-ins by (re)setting a property. That may be true for plain objects, but I think the situation is quite different for functions, because there is no equivalent to non-configurable for the [[Call]] and [[Construct]] properties. BTW, a similar issue applies to getters and setters: even if a property is non-configurable, as long as it is defined by accessors an attacker could attach to the underlying JS functions and thereby essentially redefine the property without actually modifying it. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On Tue, Nov 8, 2011 at 11:29 AM, Andreas Rossberg rossb...@google.comwrote: On 8 November 2011 19:13, Mark S. Miller erig...@google.com wrote: The reason Proxy.attach may not be fatal is that it only allows attachment to extensible objects. Our hypothesis is that any ES5 object that is interested in defending itself has already made itself non-extensible. This is why we must key this off of non-extensibility, rather than introducing a new orthogonal bit -- to avoid breaching the defenses of those ES5 era objects that tried to defend themselves. I don't think that addresses the issue I was describing. The problem is: the object itself can all be frozen, non-extensible, non-attachable just fine, but that doesn't achieve much by itself anymore because an attacker can still attach to each individual method, since they are entirely separate objects! So instead of just freezing an object, you _additionally_ would have to make all its _individual methods_ non-attachable (by whatever means). AFAICS, that affects assumptions of existing ES5 code quite severely. In general, for an object to be defensive, much of the surface reachable from it by transitive prototype and reflective property traversal should usually be frozen, and at least non-extensible. This is possible to express in ES5 http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/startSES.js#623, but inconvenient and expensive. That's why I have been advocating better defensive abstractions for ES6: const functions, const classes, traitsjs or its syntactic derivatives, etc. Nevertheless, I see your point. Many defensive ES5 abstractions will be less defensive than this. If I understand you correctly, your point is specifically about the [[Call]] and [[Construct]] traps. Perhaps we should be more conservative here, without necessarily backing away from the whole Proxy.attach idea? -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On 8 November 2011 20:46, Mark S. Miller erig...@google.com wrote: In general, for an object to be defensive, much of the surface reachable from it by transitive prototype and reflective property traversal should usually be frozen, and at least non-extensible. This is possible to express in ES5 http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/startSES.js#623, but inconvenient and expensive. That's why I have been advocating better defensive abstractions for ES6: const functions, const classes, traitsjs or its syntactic derivatives, etc. Nevertheless, I see your point. Many defensive ES5 abstractions will be less defensive than this. If I understand you correctly, your point is specifically about the [[Call]] and [[Construct]] traps. Yes. Existing code has no reason to bother making functions non-extensible if all it does is calling them. Proxy.attach fundamentally breaks that (so far correct, AFAICT) assumption. Perhaps we should be more conservative here, without necessarily backing away from the whole Proxy.attach idea? Disallowing attaching to functions with your own call/construct traps would be the minimal restriction, I think. But maybe there is something cleaner. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On Tue, Nov 8, 2011 at 12:50 PM, Andreas Rossberg rossb...@google.comwrote: On 8 November 2011 20:46, Mark S. Miller erig...@google.com wrote: Nevertheless, I see your point. Many defensive ES5 abstractions will be less defensive than this. If I understand you correctly, your point is specifically about the [[Call]] and [[Construct]] traps. Yes. Existing code has no reason to bother making functions non-extensible if all it does is calling them. Proxy.attach fundamentally breaks that (so far correct, AFAICT) assumption. I think we're agreeing on the operational point -- that much defensive code won't bother to freeze such functions. But for clarity, I must correct your no reason. The reason is one of the oldest software engineering best practices: Say What You Mean. Perhaps a clearer statement is Mean Only What You Say. The it in your above sentence presumes a non-local whole program analysis which violates this rule, and is in any case inapplicable to libraries. To keep what the program means in sync with what it seems to mean, we need to avoid introducing unexpressed communication channels. Or, put another way, unexpressed shared mutable locations. If Alice provides object C to both B and D, the only ways in which this should enable further communication between B and D (beyond that which they may have already had) should be according to the expressed behavior of C. For example, if the expressed behavior of C is completely stateless, then the fact that B and D both share a reference to C should not enable any additional communications/interaction/influence between B and D. These constraints are useful for much beyond security. If you wish to program in a mostly functional style, you'd like the deviations from functional style to only be where you've made a purposeful choice. When debugging, you need to figure out: How did the bad symptom happen? If you can bound the possible causes, by reasoning in terms of the program's intended behavior, your detective work is much easier. A program should not only work. It should also appear to work. --Carl Hewitt. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss