Re: [whatwg] Location object identity and navigation behavior
On Mon, Jan 7, 2013 at 11:17 PM, Bobby Holley bobbyhol...@gmail.com wrote: On Mon, Jan 7, 2013 at 8:05 PM, Ian Hickson i...@hixie.ch wrote: On Mon, 7 Jan 2013, Bobby Holley wrote: Aside from concerns about stack introspection, the main downside of this approach is that it's a blacklist, rather than a whitelist (like our other security code), so we'll have to be extra careful when implementing anything new on Location. Please keep that in mind when updating the spec. ;-) Can you elaborate on what is a blacklist? In the sense that we have to implement it as explicit per-method checks in C++. Our regular security model is an object-capability system enforced with wrappers across scope boundaries (using a whitelist), which, as previously discussed, doesn't jive with the current spec for Location. So if something new is ever added to nsLocation, we're going to need to remember to add a security check. The way we handle this in WebKit is with an IDL attribute [CheckDomainSecurity] on the interface that instructs the code generator to generate these security checks for each method automatically. Individual methods can be whitelisted using the IDL attribute [DoNotCheckDomainSecurity]. That's all much easier than implementing a secure JavaScript wrapper. (I understand that some existing Mozilla-proprietary features require you to spend the engineering effort to build secure JavaScript wrappers, but nothing in the web platform requires other browser engines to make that investment.) Adam
Re: [whatwg] Location object identity and navigation behavior
On Tue, 20 Nov 2012, Bobby Holley wrote: On Tue, Nov 20, 2012 at 9:46 AM, Ian Hickson i...@hixie.ch wrote: In thinking about this further last night, it struck me that while the proposed proxy mechanism was IMHO overly complex, there might be a simpler mechanism that still gets all the compatibility needs, and works for Mozilla, and isn't quite so crazy. I'm not a huge fan of this, but I'd be interested in what Adam thinks of it. Right now, as specced, each Document gets a Location object, but they all act the same: they all work on the active document and they all do security checks based on the active document, not the Location's Document. But what if, instead, we had one Location per Document, and it worked on that Document (not the active document), with the security policy being like Window, specific to its Document's effective origin, but instead of ever getting references to it, you only got references to a proxy that acted on the active document's Location? Wouldn't this effectively mean having a LocationProxy, just like WindowProxy? Yes. It differs from the original proposal in that there's multiple underlying objects and they're just proxied, not just one object that has its prototype and properties changed when the history is traversed. I'm certainly all for it, and think that it makes things much more sane, though I don't understand why this wouldn't propagate the magic that Adam doesn't want to propagate. I might be misunderstanding you though. Can you clarify? I agree that it does seem to be still more complicated than is apparently necessary, at least for implementations where determining the calling script's effective script origin is relatively easy. My understanding is that WebKit, old Gecko, and new IE do what the spec says currently, and old IE, Opera, and new Gecko do the proxying model. For authors, I don't really see the value of the proxying model. The current spec model is slightly simpler for authors, but only slightly, because you still can't access your own shims when the page is navigated to another origin. For implementors, I'm not really comfortable picking one side or the other here. I'm even less comfortable picking what's easy for Chrome over what's easy for Gecko. Browsers seem to be changing in both directions, and right now seem to be exactly equally split. So, I dunno. If it's a bust for authors, a tie for browsers, I guess the next level is spec writers, and, well, not changing anything is easier than changing something, so I guess that argues for not changing it? I've left the spec as-is for now, but I don't have a good argument one way or the other. Sorry for this unsatisfying answer. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Location object identity and navigation behavior
On Mon, Jan 7, 2013 at 12:26 PM, Ian Hickson i...@hixie.ch wrote: My understanding is that WebKit, old Gecko, and new IE do what the spec says currently, and old IE, Opera, and new Gecko do the proxying model. Given the concerns in this thread, I never landed such a change to Gecko. New Gecko == Old Gecko here. For authors, I don't really see the value of the proxying model. The current spec model is slightly simpler for authors, but only slightly, because you still can't access your own shims when the page is navigated to another origin. I still think it's less confusing for the casual author (since, like window, if the object describes the picture frame, there would appear to be one object per picture frame), though for spec-reading authors the extra LocationProxy stuff might be more confusing. For implementors, I'm not really comfortable picking one side or the other here. I'm even less comfortable picking what's easy for Chrome over what's easy for Gecko. Browsers seem to be changing in both directions, and right now seem to be exactly equally split. So, I dunno. If it's a bust for authors, a tie for browsers, I guess the next level is spec writers, and, well, not changing anything is easier than changing something, so I guess that argues for not changing it? I've left the spec as-is for now, but I don't have a good argument one way or the other. Sorry for this unsatisfying answer. No worries - I appreciate the thoroughness of consideration you've given here. And anyways, I managed to get rid of most of the nastiest stuff in Gecko's Location implementation, in exchange for explicit security checks in each C++ method implementation. Aside from concerns about stack introspection, the main downside of this approach is that it's a blacklist, rather than a whitelist (like our other security code), so we'll have to be extra careful when implementing anything new on Location. Please keep that in mind when updating the spec. ;-) Cheers, bholley
Re: [whatwg] Location object identity and navigation behavior
On Mon, 7 Jan 2013, Bobby Holley wrote: Aside from concerns about stack introspection, the main downside of this approach is that it's a blacklist, rather than a whitelist (like our other security code), so we'll have to be extra careful when implementing anything new on Location. Please keep that in mind when updating the spec. ;-) Can you elaborate on what is a blacklist? The way it ended up in the spec is that everything on Location is blocked if it's a cross-origin access, except for the 'href' setter and 'replace'. This is an area that I've already screwed up the security model for twice, though, so I would have no trouble believing I screwed it up again... http://whatwg.org/html#security-3 -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Location object identity and navigation behavior
On Mon, Jan 7, 2013 at 8:05 PM, Ian Hickson i...@hixie.ch wrote: On Mon, 7 Jan 2013, Bobby Holley wrote: Aside from concerns about stack introspection, the main downside of this approach is that it's a blacklist, rather than a whitelist (like our other security code), so we'll have to be extra careful when implementing anything new on Location. Please keep that in mind when updating the spec. ;-) Can you elaborate on what is a blacklist? In the sense that we have to implement it as explicit per-method checks in C++. Our regular security model is an object-capability system enforced with wrappers across scope boundaries (using a whitelist), which, as previously discussed, doesn't jive with the current spec for Location. So if something new is ever added to nsLocation, we're going to need to remember to add a security check. bholley
Re: [whatwg] Location object identity and navigation behavior
On 11/20/12 1:23 AM, Ian Hickson wrote: Could you elaborate in the bug? I've no idea what you think is wrong. Done, but what's wrong is that the security checks described in the spec check the origin of the wrong document. You can maintain a stack of entry scripts. You can't use a global, because you need to push and pop entry scripts as various things happen (e.g. invoking event listeners sets the entry script to the event listener function's script for the duration of the event listener invocation). The way the spec does it, the stack is implemented as the actual call stack, with nested calls to jump to a code entry-point storing the old value, updating the global, running the script, then restoring the global to the stored old value. Sure, that works. One way or another, you need to have a stack. ;) And if part of your WebAPI/DOM/etc implementation itself is done in JS you have to be careful to not update the entry-point stuff when calling into that JS, of course. The thing that _really_ requires stack introspection is when you need to look at the caller script instead of the entry script. Which is what you need to do when performing Location security checks (or indeed, any security checks). Can you show an example of when that is needed? Uh... any time you do a security check, in general. As far as I can tell, the entry script always has the same origin as the running script. All you need for script A to be able to call script B as the spec us currently written is that sometime in the past the effective script origin of A matched the effective script origin of some script C and that at some point in the past (possibly a completely different point) the effective script origin of B matched the effective script origin of C (which may not have been the same at that point as when C matched A!). There is no requirement that A ever matched B, or even that the sets of effective script origins A and B have had in the past have nonempty intersection. And even that may not be true depending on whether UAs allow privileged JS in various settings. If they do, then the entry script becomes very useless for origin determination unless crossing origin barriers resets the entry script. Which, again, is not the case in Gecko right now. But that's obviously Gecko's problem, for the moment. I guess this isn't necessarily true of the effective origin, which is what we're using for the Location object security? Is that the problem here? I think the problem is that you're assuming invariants that just don't hold. There is no current requirement in the spec that there be any relationship between either the origin or effective script origin of the entry script and the origins of the currently running script. If so, why don't we just make it be an origin check of the entry script instead of an effective origin check? Because that would be totally wrong; see above. If that would make it simpler for Gecko As things stand, it wouldn't, particularly. It would actually introduce security bugs. if you have both calling each other then you can almost certainly trick the script into doing what you want either way. Who said anything about both calling each other? Gecko's security model is asymmetric in practice. -Boris
Re: [whatwg] Location object identity and navigation behavior
On Tue, 20 Nov 2012, Boris Zbarsky wrote: All you need for script A to be able to call script B as the spec us currently written is that sometime in the past the effective script origin of A matched the effective script origin of some script C and that at some point in the past (possibly a completely different point) the effective script origin of B matched the effective script origin of C (which may not have been the same at that point as when C matched A!). I have great difficulty worrying about C accessing A. If you set document.domain and yet don't trust the other side, you've basically lost. Don't do that. IMHO there's no point us trying to keep things locked down when you set document.domain. I'd be fine with making all the security checks still use the entry script's real origin, except that Window would now allow you access to stuff you didn't have access to before. I think the problem is that you're assuming invariants that just don't hold. There is no current requirement in the spec that there be any relationship between either the origin or effective script origin of the entry script and the origins of the currently running script. Because of document.domain. Yeah. Man I wish we could just kill document.domain. if you have both calling each other then you can almost certainly trick the script into doing what you want either way. Who said anything about both calling each other? If they're not calling each other, how are they both on the stack? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Location object identity and navigation behavior
On 11/20/12 2:38 AM, Ian Hickson wrote: IMHO there's no point us trying to keep things locked down when you set document.domain. I believe sites actually rely on a certain amount of lockdown in situations like this... Adam can fill you in, I'm sure. But in general, as people work more and more on Widgety and Appy stuff in HTML, with various expanded privileges, granted permissions, etc, the assumption that the security model is completely symmetric just becomes false. I'd rather we didn't paint ourselves into a corner by assuming otherwise here and requiring behavior that UAs would simply refuse to implement because they view it as insecure. if you have both calling each other then you can almost certainly trick the script into doing what you want either way. Who said anything about both calling each other? If they're not calling each other, how are they both on the stack? This only requires one of them calling the other. It doesn't require the other being able to call back into one. Maybe that's not what you meant, though. So let me give you a concrete not-exactly-hypothetical example. Say I'm implementing a debugger in a web browser, and I implement my UI in HTML+JS as browsers are tending to do now. When I examine properties with scripted getters in this debugger, what should happen? I will bet money that the debugger is not, generally, running with the permissions of the page, because it needs to be able to do things that web pages aren't allowed to do. However the getters in question had better run with the permissions of the page; otherwise you open up the debugger to attacks from the web page. This problem is not solvable using the separate worlds approaches browsers use to provide extensions with an unmodified view of the DOM, since the debugger really does want to see what's going on in the web page itself; it just doesn't want to allow the page to escalate permissions. Now I know there are several possible objections to this use case, so let me just pre-address some: 1) It's not the web, so we don't have to specify it. That's true, sure. I suspect as time goes on we might in fact need to specify something like this for apps, however. And more importantly, just because it's not the web doesn't mean UAs are not implementing it, and if they're implementing it they need to make it work with their security model, whatever it is. 2) The debugger can have some magic to make it all work. Yes, but then the question is how it interacts with the web security model and how the result can be implemented. 3) The debugger should set the entry script before invoking the getter. This is a plausible approach, but it makes it very error-prone and complicated to create things like the above-described debugger: you have to manually keep track of which objects come from where instead of just having the web platform implementation (which already has that information) keep track of it for you. 4) Entry script should always be set when crossing origins (for some definition of crossing origins). This seems plausible as well. Maybe it's doable. One other note: Gecko's current model is at least somewhat influenced by the fact that in the past Gecko had expanded privileges on a per-function basis. This obviously made using the entry script a non-starter... Maybe it's more of a starter now. I'll let Bobby worry about it. ;) -Boris
Re: [whatwg] Location object identity and navigation behavior
On Tue, Nov 20, 2012 at 9:46 AM, Ian Hickson i...@hixie.ch wrote: Given the way JavaScript works, I just don't see a sane way to make a non-symmetric model work. JS just allows too much introspection. Any time you pass a string from one to the other, you're also passing a way for the callee to call back into the caller, for example (via the string's methods). Passing any sort of structured objects similarly means passing mehods. Callbacks are also a very widely used pattern. We actually implement this. It's pretty off-topic for the thread at this point, but I'd be happy to talk about it in a separate thread or on IRC if you're interested. I'd also be interested to hear your thoughts about it. Anyway, we're kind of getting away from the original topic here, which isn't fully resolved; Location. In thinking about this further last night, it struck me that while the proposed proxy mechanism was IMHO overly complex, there might be a simpler mechanism that still gets all the compatibility needs, and works for Mozilla, and isn't quite so crazy. I'm not a huge fan of this, but I'd be interested in what Adam thinks of it. Right now, as specced, each Document gets a Location object, but they all act the same: they all work on the active document and they all do security checks based on the active document, not the Location's Document. But what if, instead, we had one Location per Document, and it worked on that Document (not the active document), with the security policy being like Window, specific to its Document's effective origin, but instead of ever getting references to it, you only got references to a proxy that acted on the active document's Location? Wouldn't this effectively mean having a LocationProxy, just like WindowProxy? I'm certainly all for it, and think that it makes things much more sane, though I don't understand why this wouldn't propagate the magic that Adam doesn't want to propagate. I might be misunderstanding you though. Can you clarify?
Re: [whatwg] Location object identity and navigation behavior
On 11/20/12 12:46 PM, Ian Hickson wrote: Given the way JavaScript works, I just don't see a sane way to make a non-symmetric model work. How does JavaScript work in your mind? We have a good amount of experience making a non-symmetric model work in Gecko, for what it's worth. Any time you pass a string from one to the other, you're also passing a way for the callee to call back into the caller, for example (via the string's methods). Spidermonkey effectively copies strings when passing across globals; the callee never gets the caller's actual string. The methods the callee sees on strings are its own methods, not the callers. Passing any sort of structured objects similarly means passing mehods. In the case of Gecko, what the caller gets in this case is a proxy for the actual object which enforces security invariants like only properties on a whitelist are exposed for cases when the security check is asymmetric. This is handled completely on the underlying JS implementation level; individual callers don't have to do anything special to be safe this way. We have mechanisms for safe passing of data from one context to another, such as postMessage(). Doing it by having one-way glass in JS just seems like asking for trouble. postMessage doesn't work unless both sides are cooperating... Yeah, like running getters with the ability to abort them if they don't return promptly. Perhaps, yes. ;) I agree that debuggers have all sorts of weird going on, obviously! But your underlying point, that we can't rely on the entry script and the real origin, is sound. In particular, anything that's to be affected by document.domain has to use the calling script, not the entry script, and has to use the effective origin, not the real origin. It would be useful if someone (other than me) were to review the spec's uses of the term entry script and origin and verify that the checks all make sense. I'll see what I can do about finding someone for this. Might be a few weeks given holidays and whatnot, obviously. I'll let Bobby handle the Location parts of this. ;) -Boris
Re: [whatwg] Location object identity and navigation behavior
On Thu, 8 Nov 2012, Bobby Holley wrote: The current spec for the Location object doesn't match reality. At the moment, the spec says that Location is a per-Window object that describes the associated Document. However, in our testing, it appears that none of the user-agents (Gecko, WebKit, Trident, Presto) do this [1]. Instead, all implementations of Location describe the active document in the browsing context (that is to say, the referent of the WindowProxy). This suggests that the spec's current language is likely not web-compatible. Fixed. If the Location object describes the browsing context, we're left to consider whether there should be one Location object per Window or one Location object per browsing context. Gecko and Webkit currently do the former, and Trident and Presto do the latter (see again [1]). It seems IE changed in IE10 and now acts like WebKit. Arguments for the one-LocationProxy-per-WindowProxy behaviour: - it would likely improve Gecko's security story since it would simplify Gecko's security invariants. - it's what Opera and old IEs implement (I think?). Arguments for the one-Location-per-Window behaviour: - it would likely improve WebKit's security story since it would simplify Webkit's security checks (relative to the other option). - it's what WebKit and new IEs implement (I think?). - it has the clearer story for authors. Objects that change identity, or that gain or lose properties when a page navigates, are unintuitive. On Thu, 8 Nov 2012, Boris Zbarsky wrote: On 11/8/12 6:09 PM, Adam Barth wrote: In WebKit at least, it would be a security vulnerability to expose JavaScript objects that belong to Document B to Document A because that would give Document A access to the prototype objects for Document B. You presumably have a solution for this situation for the WindowProxy case, right? Certainly Gecko does, and we would be using the same solution for Location if we tie the lifetime of a Location to the lifetime of a WindowProxy. This problem exists regardless of whether we have proxies, since the Location object is visible cross-origin. Whether we proxy or not is orthogonal. The question is just how we should protect the object. On Fri, 9 Nov 2012, Adam Barth wrote: The WindowProxy is a special, magical object because references to it magically change which JavaScript object they refer to over time. If possible, I would like to avoid infecting other objects with its magic. I do agree with this. I don't see why we would ever introduce an object like this if we can help it. On Fri, 9 Nov 2012, Bobby Holley wrote: Right now, the Location object is the only object whose security characteristics are not guaranteed to match its global, which is a major pain point for us. The Window object, the Document object, and the Location object, per spec, all have exactly the same security characteristics, except that Window and Location have certain properties that can be accessed. (This is also quite similar to the Storage model, except Storage uses the actual origin, not the effective script origin.) On Fri, 9 Nov 2012, Bobby Holley wrote: As noted, the Location object is the only object whose security characteristics don't match its scope. This requires a lot of extra goop in our compartment-based security model, and the goop is brittle (recently forcing us to release two out-of-band updates, 16.0.1 and 16.0.2). We've got enough belt-and-suspenders code now that I'm not particularly worried, but I still want to make Location just like any other object from a security perspective. I don't think making it one of those proxy objects, of which there's only one so far and it's very complicated, is making it just like any other object, but I understand that the Gecko security model does make this different than it first appears. Also, FWIW, from the perspective of an average web-developer, IMO it makes much more semantic sense to have one Location per WindowProxy if the Location object describes the WindowProxy. It has some pretty serious implications. It means if you have the object in an iframe and install a shim to implement some of Anne's new features, your shim will break as soon as you navigate the iframe. That's very odd. It also means that the object's instanceof characteristic will keep changing. Again, very unusual and not something authors normally see. On Fri, 9 Nov 2012, Boris Zbarsky wrote: One thing I'd like is some comment from Opera and Microsoft about what their situation is, since implementing what WebKit does would mean both of those changing. This is probably the wrong venue to get hold of Microsoft for an official statement, sadly. :( Microsoft seems to have already changed, from what I hear of IE10 (I unfortunately don't have access to an instance to test for myself). Input from Opera people would indeed be welcome. On
Re: [whatwg] Location object identity and navigation behavior
On 11/19/12 8:38 PM, Ian Hickson wrote: For now I've tightened up the spec so it should be implementable, secure, and Web-compatible I don't believe it's secure as currently written, actually. Filed https://www.w3.org/Bugs/Public/show_bug.cgi?id=20012 I'm also curious as to why figuring out the entry script's characteristics needs to use the stack introspection rather than just having an event-loop global first script variable You can maintain a stack of entry scripts. You can't use a global, because you need to push and pop entry scripts as various things happen (e.g. invoking event listeners sets the entry script to the event listener function's script for the duration of the event listener invocation). There is no such stack of entry scripts in Gecko yet, but we're working on changing that. The thing that _really_ requires stack introspection is when you need to look at the caller script instead of the entry script. Which is what you need to do when performing Location security checks (or indeed, any security checks). -Boris
Re: [whatwg] Location object identity and navigation behavior
On Mon, 19 Nov 2012, Boris Zbarsky wrote: On 11/19/12 8:38 PM, Ian Hickson wrote: For now I've tightened up the spec so it should be implementable, secure, and Web-compatible I don't believe it's secure as currently written, actually. Filed https://www.w3.org/Bugs/Public/show_bug.cgi?id=20012 Could you elaborate in the bug? I've no idea what you think is wrong. I'm also curious as to why figuring out the entry script's characteristics needs to use the stack introspection rather than just having an event-loop global first script variable You can maintain a stack of entry scripts. You can't use a global, because you need to push and pop entry scripts as various things happen (e.g. invoking event listeners sets the entry script to the event listener function's script for the duration of the event listener invocation). The way the spec does it, the stack is implemented as the actual call stack, with nested calls to jump to a code entry-point storing the old value, updating the global, running the script, then restoring the global to the stored old value. There is no such stack of entry scripts in Gecko yet, but we're working on changing that. The thing that _really_ requires stack introspection is when you need to look at the caller script instead of the entry script. Which is what you need to do when performing Location security checks (or indeed, any security checks). Can you show an example of when that is needed? As far as I can tell, the entry script always has the same origin as the running script. I guess this isn't necessarily true of the effective origin, which is what we're using for the Location object security? Is that the problem here? If so, why don't we just make it be an origin check of the entry script instead of an effective origin check? If that would make it simpler for Gecko, that's fine by me. I don't really see why it would matter in this case anyway; if you have both calling each other then you can almost certainly trick the script into doing what you want either way. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Location object identity and navigation behavior
On 11/08/2012 07:19 PM, Bobby Holley wrote: The current spec for the Location object doesn't match reality. At the moment, the spec says that Location is a per-Window object that describes the associated Document. However, in our testing, it appears that none of the user-agents (Gecko, WebKit, Trident, Presto) do this [1]. Instead, all implementations of Location describe the active document in the browsing context (that is to say, the referent of the WindowProxy). This suggests that the spec's current language is likely not web-compatible. If the Location object describes the browsing context, we're left to consider whether there should be one Location object per Window or one Location object per browsing context. Gecko and Webkit currently do the former, and Trident and Presto do the latter (see again [1]). I would like to change Gecko's behavior here [2], because would simplify a lot of security invariants and generally make things more sane. How do WebKit folks feel about this? If Location follows the WindowProxy, an interesting question is what happens to expando properties on navigation. I did some testing, and UAs seem to have pretty inconsistent behavior here [3]. As such, I think the sanest policy is simply to clear expandos on Location each time the page is navigated. This is the approach I've taken in the patches in [2]. Thoughts? Nothing specific on the design, but whatever the final consensus here is *please* submit your testcases for everyone to use. This stuff is difficult, and very hard to write tests for when you are not actively implementing. Without a good shared library of tests in this area we will probably have bad interoperability for many years to come.
Re: [whatwg] Location object identity and navigation behavior
On Thu, Nov 8, 2012 at 10:21 PM, Boris Zbarsky bzbar...@mit.edu wrote: On 11/8/12 6:09 PM, Adam Barth wrote: I don't think I quite understand what you mean, but the way this works in WebKit is that each Window object has its own Location object. That's not how it works in Presto and Trident, as far as we can tell based on testing with ==. In those, each WindowProxy has its own Location object. The location object operates on the current Window for the WindowProxy. Yes. _That_ all browsers are consistent on, and is totally not what the spec says right now. In the spec, there is one Location per Window, and the object operates on the Window it's associated with. The fact that this does not match any browsers is what makes us suspect the spec is not web-compatible. In WebKit at least, it would be a security vulnerability to expose JavaScript objects that belong to Document B to Document A because that would give Document A access to the prototype objects for Document B. You presumably have a solution for this situation for the WindowProxy case, right? Certainly Gecko does, and we would be using the same solution for Location if we tie the lifetime of a Location to the lifetime of a WindowProxy. The WindowProxy is a special, magical object because references to it magically change which JavaScript object they refer to over time. If possible, I would like to avoid infecting other objects with its magic. Adam
Re: [whatwg] Location object identity and navigation behavior
On Fri, Nov 9, 2012 at 9:30 AM, Adam Barth w...@adambarth.com wrote: On Thu, Nov 8, 2012 at 10:21 PM, Boris Zbarsky bzbar...@mit.edu wrote: You presumably have a solution for this situation for the WindowProxy case, right? Certainly Gecko does, and we would be using the same solution for Location if we tie the lifetime of a Location to the lifetime of a WindowProxy. The WindowProxy is a special, magical object because references to it magically change which JavaScript object they refer to over time. If possible, I would like to avoid infecting other objects with its magic. That was my opinion for a while, too, but I eventually decided it was necessary in Gecko. Right now, the Location object is the only object whose security characteristics are not guaranteed to match its global, which is a major pain point for us. I think the current spec language would be the most ideal approach, but as noted I doubt it'll fly on the web. FWIW, this turned out to be much simpler to implement than I thought. We've already worked out where we need to put the logic to make WindowProxy update appropriately, and we already had code to move objects like Location between scopes (which we needed to do for document.write). I'd imagine WebKit has the former, though I'm not sure about the latter. bholley
Re: [whatwg] Location object identity and navigation behavior
On Fri, Nov 9, 2012 at 12:06 PM, Bobby Holley bobbyhol...@gmail.com wrote: On Fri, Nov 9, 2012 at 11:33 AM, Adam Barth w...@adambarth.com wrote: That was my opinion for a while, too, but I eventually decided it was necessary in Gecko. Can you explain why you think it is necessary? In WebKit, the WindowProxy is the only object that has this magic. As noted, the Location object is the only object whose security characteristics don't match its scope. This requires a lot of extra goop in our compartment-based security model, and the goop is brittle (recently forcing us to release two out-of-band updates, 16.0.1 and 16.0.2). We've got enough belt-and-suspenders code now that I'm not particularly worried, but I still want to make Location just like any other object from a security perspective. If UAs were consistent or the spec matched reality, this would be a different story. But given that we probably need to change the spec to either the Trident/Presto model or the Gecko/WebKit model, I support the former, because we've historically had problems implementing the latter securely. Do you feel that it would be difficult to implement the former securely in WebKit? That depends on the questions I asked earlier. Also, FWIW, from the perspective of an average web-developer, IMO it makes much more semantic sense to have one Location per WindowProxy if the Location object describes the WindowProxy. But I doubt many people touch this stuff in practice. I don't think the average web developer will hit this case because it depends on interacting with the Location object in an inactive document. We don't want to move objects between scopes. That causes many security complications that we don't want to deal with. Are you able to just update references, like you do with WindowProxy? That's the magic I don't want to proliferate. That's essentially what we're doing. We actually create a new object in the new scope and update all the old references to point to it. Can you answer the questions in my previous email? Which ones? AFAICT Boris answered all of them except for the testcase thing (which I answered). Did I miss some? Maybe I didn't receive your email. I gave some example code and asked which values were printed: ---8--- Consider the following case: == Document A == script Object.prototype.foo = A1; window.location.bar = A2; function f() { var loc = window.location; print(loc.foo); // print is a magic function that lets me see this value print(loc.bar); } /script == Document B == script Object.prototype.foo = B1; window.location.bar = B2; /script 1) Document A is displayed in browsing context X. 2) Browsing context X is navigated and now displays document B. 3) Function f is called. What values are printed? ---8--- Adam
Re: [whatwg] Location object identity and navigation behavior
On Fri, Nov 9, 2012 at 9:43 AM, Bobby Holley bobbyhol...@gmail.com wrote: On Fri, Nov 9, 2012 at 9:30 AM, Adam Barth w...@adambarth.com wrote: On Thu, Nov 8, 2012 at 10:21 PM, Boris Zbarsky bzbar...@mit.edu wrote: You presumably have a solution for this situation for the WindowProxy case, right? Certainly Gecko does, and we would be using the same solution for Location if we tie the lifetime of a Location to the lifetime of a WindowProxy. The WindowProxy is a special, magical object because references to it magically change which JavaScript object they refer to over time. If possible, I would like to avoid infecting other objects with its magic. That was my opinion for a while, too, but I eventually decided it was necessary in Gecko. Can you explain why you think it is necessary? In WebKit, the WindowProxy is the only object that has this magic. Right now, the Location object is the only object whose security characteristics are not guaranteed to match its global, which is a major pain point for us. I think the current spec language would be the most ideal approach, but as noted I doubt it'll fly on the web. FWIW, this turned out to be much simpler to implement than I thought. We've already worked out where we need to put the logic to make WindowProxy update appropriately, and we already had code to move objects like Location between scopes (which we needed to do for document.write). I'd imagine WebKit has the former, though I'm not sure about the latter. We don't want to move objects between scopes. That causes many security complications that we don't want to deal with. Can you answer the questions in my previous email? Adam
Re: [whatwg] Location object identity and navigation behavior
On Fri, Nov 9, 2012 at 11:33 AM, Adam Barth w...@adambarth.com wrote: That was my opinion for a while, too, but I eventually decided it was necessary in Gecko. Can you explain why you think it is necessary? In WebKit, the WindowProxy is the only object that has this magic. As noted, the Location object is the only object whose security characteristics don't match its scope. This requires a lot of extra goop in our compartment-based security model, and the goop is brittle (recently forcing us to release two out-of-band updates, 16.0.1 and 16.0.2). We've got enough belt-and-suspenders code now that I'm not particularly worried, but I still want to make Location just like any other object from a security perspective. If UAs were consistent or the spec matched reality, this would be a different story. But given that we probably need to change the spec to either the Trident/Presto model or the Gecko/WebKit model, I support the former, because we've historically had problems implementing the latter securely. Do you feel that it would be difficult to implement the former securely in WebKit? Also, FWIW, from the perspective of an average web-developer, IMO it makes much more semantic sense to have one Location per WindowProxy if the Location object describes the WindowProxy. But I doubt many people touch this stuff in practice. We don't want to move objects between scopes. That causes many security complications that we don't want to deal with. Are you able to just update references, like you do with WindowProxy? That's essentially what we're doing. We actually create a new object in the new scope and update all the old references to point to it. Can you answer the questions in my previous email? Which ones? AFAICT Boris answered all of them except for the testcase thing (which I answered). Did I miss some? Cheers, bholley
Re: [whatwg] Location object identity and navigation behavior
On Fri, Nov 9, 2012 at 12:17 PM, Adam Barth w...@adambarth.com wrote: I don't think the average web developer will hit this case because it depends on interacting with the Location object in an inactive document. Agreed. Maybe I didn't receive your email. Here's a link to it in the archives: http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-November/037850.html
Re: [whatwg] Location object identity and navigation behavior
On Fri, Nov 9, 2012 at 12:26 PM, Bobby Holley bobbyhol...@gmail.com wrote: On Fri, Nov 9, 2012 at 12:17 PM, Adam Barth w...@adambarth.com wrote: I don't think the average web developer will hit this case because it depends on interacting with the Location object in an inactive document. Agreed. Maybe I didn't receive your email. Here's a link to it in the archives: http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-November/037850.html Thanks for the link. Somehow the message got routed to spam. It's possible we could implement that in WebKit, but the implementation would be very delicate. We currently implement similar security checks for Location because Location is visible across origins. The main difficulty would be implementing the WindowProxy-like re-writing of existing references. I understand that implementing that behavior in Gecko is much easier than in WebKit because Gecko makes extensive use of JavaScript wrapper objects. We have avoided introducing similar wrapper objects in WebKit because they're quite subtle and can lead to security vulnerabilities if used incorrectly. I don't fully understand why the current behavior is fragile in Gecko. The approach we use in WebKit is quite simple---we just perform an access check before doing any sensitive operations. This access check is required in any case because the underlying Location object is visible across origins. I guess the issue must be that Gecko performs the access check based on some property of the JavaScript object. In WebKit, we simply perform the access check based on the operation we're actually about to perform, irrespective of what API was used to trigger the action. Adam
Re: [whatwg] Location object identity and navigation behavior
On 11/9/12 2:05 PM, Adam Barth wrote: The approach we use in WebKit is quite simple---we just perform an access check before doing any sensitive operations. The issue in Gecko, as I understand, is that security checks from C++ code require introspecting running JS to figure out what the right actor (subject) origin for the security check is. This is somewhat fragile because it's easy to accidentally interpose other things that look like running JS between the caller and callee in many cases. Note that this problem would be even worse for a self-hosted (implemented in JS) implementation of something like Location... The upshot is that instead we aim to do security checks at points where control crosses from one origin to another, and use proxies to enforce the security invariants involved. Bobby knows more about this than I do, so I'll let him correct any inaccuracies. This access check is required in any case because the underlying Location object is visible across origins. In Gecko, it's actually not. A proxy is visible. One thing I'd like is some comment from Opera and Microsoft about what their situation is, since implementing what WebKit does would mean both of those changing. This is probably the wrong venue to get hold of Microsoft for an official statement, sadly. :( -Boris
[whatwg] Location object identity and navigation behavior
The current spec for the Location object doesn't match reality. At the moment, the spec says that Location is a per-Window object that describes the associated Document. However, in our testing, it appears that none of the user-agents (Gecko, WebKit, Trident, Presto) do this [1]. Instead, all implementations of Location describe the active document in the browsing context (that is to say, the referent of the WindowProxy). This suggests that the spec's current language is likely not web-compatible. If the Location object describes the browsing context, we're left to consider whether there should be one Location object per Window or one Location object per browsing context. Gecko and Webkit currently do the former, and Trident and Presto do the latter (see again [1]). I would like to change Gecko's behavior here [2], because would simplify a lot of security invariants and generally make things more sane. How do WebKit folks feel about this? If Location follows the WindowProxy, an interesting question is what happens to expando properties on navigation. I did some testing, and UAs seem to have pretty inconsistent behavior here [3]. As such, I think the sanest policy is simply to clear expandos on Location each time the page is navigated. This is the approach I've taken in the patches in [2]. Thoughts? Cheers, bholley [1] http://people.mozilla.org/~mwobensmith/window_test/doc_win.htm [2] https://bugzilla.mozilla.org/show_bug.cgi?id=808608 [3] https://bugzilla.mozilla.org/show_bug.cgi?id=808608#c8
Re: [whatwg] Location object identity and navigation behavior
On Thu, Nov 8, 2012 at 10:19 AM, Bobby Holley bobbyhol...@gmail.com wrote: The current spec for the Location object doesn't match reality. At the moment, the spec says that Location is a per-Window object that describes the associated Document. However, in our testing, it appears that none of the user-agents (Gecko, WebKit, Trident, Presto) do this [1]. Instead, all implementations of Location describe the active document in the browsing context (that is to say, the referent of the WindowProxy). This suggests that the spec's current language is likely not web-compatible. If the Location object describes the browsing context, we're left to consider whether there should be one Location object per Window or one Location object per browsing context. Gecko and Webkit currently do the former, and Trident and Presto do the latter (see again [1]). I would like to change Gecko's behavior here [2], because would simplify a lot of security invariants and generally make things more sane. How do WebKit folks feel about this? I'm not sure I quite understand what you mean here. Can you describe an experiment that would distinguish these cases? I looked at [1], but it was too complicated for me to understand quickly. Consider the following case: == Document A == script Object.prototype.foo = A1; window.location.bar = A2; function f() { var loc = window.location; print(loc.foo); // print is a magic function that lets me see this value print(loc.bar); } /script == Document B == script Object.prototype.foo = B1; window.location.bar = B2; /script 1) Document A is displayed in browsing context X. 2) Browsing context X is navigated and now displays document B. 3) Function f is called. What values are printed? If Location follows the WindowProxy, an interesting question is what happens to expando properties on navigation. I did some testing, and UAs seem to have pretty inconsistent behavior here [3]. As such, I think the sanest policy is simply to clear expandos on Location each time the page is navigated. This is the approach I've taken in the patches in [2]. I don't think I quite understand what you mean, but the way this works in WebKit is that each Window object has its own Location object. The location object operates on the current Window for the WindowProxy. In WebKit at least, it would be a security vulnerability to expose JavaScript objects that belong to Document B to Document A because that would give Document A access to the prototype objects for Document B. Adam
Re: [whatwg] Location object identity and navigation behavior
On 11/8/12 6:09 PM, Adam Barth wrote: I don't think I quite understand what you mean, but the way this works in WebKit is that each Window object has its own Location object. That's not how it works in Presto and Trident, as far as we can tell based on testing with ==. In those, each WindowProxy has its own Location object. The location object operates on the current Window for the WindowProxy. Yes. _That_ all browsers are consistent on, and is totally not what the spec says right now. In the spec, there is one Location per Window, and the object operates on the Window it's associated with. The fact that this does not match any browsers is what makes us suspect the spec is not web-compatible. In WebKit at least, it would be a security vulnerability to expose JavaScript objects that belong to Document B to Document A because that would give Document A access to the prototype objects for Document B. You presumably have a solution for this situation for the WindowProxy case, right? Certainly Gecko does, and we would be using the same solution for Location if we tie the lifetime of a Location to the lifetime of a WindowProxy. -Boris P.S. I'll leave it to Matt and Bobby to answer your question about your testcase with function f(), because while I suspect I know what UAs do there in practice there is no way to tell without actually testing...