Re: [whatwg] Modifying the URL inside beforeunload event
On Fri, Nov 14, 2014 at 6:04 PM, Ian Hickson i...@hixie.ch wrote: On Fri, 14 Nov 2014, cowwoc wrote: 1. Say we have two pages: OLD and NEW. 2. OLD contains a link to NEW. 3. I start off on OLD and click on the link. 4. The above logic runs (beforeunload event handler changes the URL using history.replaceState() from OLD to CHANGED) 5. The browser navigates to the NEW page. 6. Now... when the user examines the URL associated with the back-button, should he see OLD or CHANGED? Unless I'm missing something, I'm pretty sure it should be CHANGED. I see no reason why it would make a difference whether the replaceState() call happens before or during the beforeunload handler; in either case, the history traversal hasn't happened yet. I'm the chromium engineer who declined the bug originally, sorry for being late to the discussion. I agree that the url being CHANGED is probably the most logical result. However, all of the browsers I tested (chromium, webkit, gecko, an older IE) showed OLD, though gecko showed CHANGED if steps 5 and 6 are repeated. I'm fine with this interpretation and changing the chromium behavior, but it's not the consensus implementation right now. ~Nate Personally the way I build apps these days is to just serve static files over HTTP, and do all the dynamic stuff over WebSocket, which would sidestep all these issues. You mean you have a single-paged application and rewrite the underlying page asynchronously? More or less. Google Calendar is an example of the kind of app I mean (though obviously that's not one I've written myself!). How do you deal with needing to load different Javascript files per page? You either load it all asynchronously, or you load it on-demand. Depends on your precise setup. Generally speaking I find that most of the logic ends up on the server; there's just not that much to do purely on the client side. Obviously that depends on how sophisticated the app is. If it's a game with crazy visuals, there's comparatively more client-side code. Similarly, if you have a rich-text editor with offline capabilities, there's obviously much more client-side code. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Modifying the URL inside beforeunload event
On Thu, 13 Nov 2014, cowwoc wrote: In any case, the question seems to be whether history.replaceState() should be honored in beforeunload. Individually, each one is very well defined, but I don't see any discussion of what should happen when the two are used together. You just follow their algorithms. I don't understand what needs to be additionally specified. Can you elaborate? The beforeunload algorithm is here: https://html.spec.whatwg.org/#prompt-to-unload-a-document You get to step 4, then run script, which calls replaceState's algorithm: https://html.spec.whatwg.org/#dom-history-replacestate The session history entry gets updated. Then you return to beforeunload, starting at step 5. Eventually 'salvageable' gets set to false, and much later (when running the 'unload' algorithm) the doc gets discarded, without affecting the (mutated) session history entry. Are you saying that history.replaceState() should succeed or fail in this case? It should do what is specified. I'm not sure what succeed or fail would mean in this context. If you don't want the tabId to be shared, you shouldn't put it in the location bar in the first place -- removing it from the history is too late, because people copy and paste URLs from the location bar while the page is up. You could replaceState() during page load, but I would generally much more recommend sessionStorage for this purpose. Using sessionStorage alone wouldn't work because the goal of this exercise is to send the server a different authentication token per browser tab. I can store these tokens in the sessionStorage (in fact, I do) but that's not enough because the browser still needs to send the token to the server with each request. I hope this clarifies my dilemma. http://stackoverflow.com/a/26901232/14731 explains how my current implementation works. It's very lengthy and ugly so I'm more than happy to entertain alternatives. Personally the way I build apps these days is to just serve static files over HTTP, and do all the dynamic stuff over WebSocket, which would sidestep all these issues. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Modifying the URL inside beforeunload event
On 14/11/2014 6:39 PM, Ian Hickson wrote: On Thu, 13 Nov 2014, cowwoc wrote: In any case, the question seems to be whether history.replaceState() should be honored in beforeunload. Individually, each one is very well defined, but I don't see any discussion of what should happen when the two are used together. You just follow their algorithms. I don't understand what needs to be additionally specified. Can you elaborate? The beforeunload algorithm is here: https://html.spec.whatwg.org/#prompt-to-unload-a-document You get to step 4, then run script, which calls replaceState's algorithm: https://html.spec.whatwg.org/#dom-history-replacestate The session history entry gets updated. Then you return to beforeunload, starting at step 5. Eventually 'salvageable' gets set to false, and much later (when running the 'unload' algorithm) the doc gets discarded, without affecting the (mutated) session history entry. Are you saying that history.replaceState() should succeed or fail in this case? It should do what is specified. I'm not sure what succeed or fail would mean in this context. I appreciate your patience. Bare with me a little longer. I understood everything you wrote below up until the last sentence: the doc gets discarded, without affecting the (mutated) session history entry. I think you meant that the mutated session history entry gets kept, but to be certain I understood you correctly I'll rephrase the question: 1. Say we have two pages: OLD and NEW. 2. OLD contains a link to NEW. 3. I start off on OLD and click on the link. 4. The above logic runs (beforeunload event handler changes the URL using history.replaceState() from OLD to CHANGED) 5. The browser navigates to the NEW page. 6. Now... when the user examines the URL associated with the back-button, should he see OLD or CHANGED? Based on what you wrote above, I think the user should see CHANGED. Did I understand you correctly? Personally the way I build apps these days is to just serve static files over HTTP, and do all the dynamic stuff over WebSocket, which would sidestep all these issues. You mean you have a single-paged application and rewrite the underlying page asynchronously? How do you deal with needing to load different Javascript files per page? I guess you could simply load all the JS files all your pages would ever need, but I assume you do something a little more sophisticated. Thanks, Gili
Re: [whatwg] Modifying the URL inside beforeunload event
On 2014-11-15 02:08, cowwoc wrote: Personally the way I build apps these days is to just serve static files over HTTP, and do all the dynamic stuff over WebSocket, which would sidestep all these issues. You mean you have a single-paged application and rewrite the underlying page asynchronously? How do you deal with needing to load different Javascript files per page? I guess you could simply load all the JS files all your pages would ever need, but I assume you do something a little more sophisticated. Thanks, Gili The way you did it was with what I call a one shot cookie. A project I worked on I did a solution where sessionStorage was used to keep a token and a cookie was set via javascript and thus sent along with the request to the server which then tells the browser to delete the cookie in the reply. If the token needs updating then the server can send a one shot cookie to the browser, the javascript will then apply the needed changes to generate a new token (maybe a new salt or nonce is given) and then delete the cookie. Also, this form of cookie use does not fall under the cookie law in Europe AFAIK as it's part of a login mechanism so no need to show those annoying this site/page uses cookies box or warning. Using sessionStorage, and cookies to pass info to/from the server is my new preferred way as you can control how often the cookies are sent and to what part of the site. The solution is not as elegant as I'd like it though. One issue is you can't set the timeout for a cookie (sent from the server) to 0 or 1 sec or similar as the browser could delete the cookie before your javascript can get the data from it. In the other direction the issue is reliably deleting the cookie after it has been sent (sometimes one can use POST requests and avoid this part, but that may not always be practical). Looking at http://stackoverflow.com/questions/26556749/binding-tab-specific-data-to-an-http-get-request the solution you ended up with is very similar to what I ended up doing, I'm not aware of any better way to do this (yet). Regards, Roger. -- Roger Rescator Hågensen. Freelancer - http://www.EmSai.net/
Re: [whatwg] Modifying the URL inside beforeunload event
On Fri, 14 Nov 2014, cowwoc wrote: 1. Say we have two pages: OLD and NEW. 2. OLD contains a link to NEW. 3. I start off on OLD and click on the link. 4. The above logic runs (beforeunload event handler changes the URL using history.replaceState() from OLD to CHANGED) 5. The browser navigates to the NEW page. 6. Now... when the user examines the URL associated with the back-button, should he see OLD or CHANGED? Unless I'm missing something, I'm pretty sure it should be CHANGED. I see no reason why it would make a difference whether the replaceState() call happens before or during the beforeunload handler; in either case, the history traversal hasn't happened yet. Personally the way I build apps these days is to just serve static files over HTTP, and do all the dynamic stuff over WebSocket, which would sidestep all these issues. You mean you have a single-paged application and rewrite the underlying page asynchronously? More or less. Google Calendar is an example of the kind of app I mean (though obviously that's not one I've written myself!). How do you deal with needing to load different Javascript files per page? You either load it all asynchronously, or you load it on-demand. Depends on your precise setup. Generally speaking I find that most of the logic ends up on the server; there's just not that much to do purely on the client side. Obviously that depends on how sophisticated the app is. If it's a game with crazy visuals, there's comparatively more client-side code. Similarly, if you have a rich-text editor with offline capabilities, there's obviously much more client-side code. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Modifying the URL inside beforeunload event
On 14/11/2014 8:56 PM, Roger Hågensen wrote: On 2014-11-15 02:08, cowwoc wrote: Personally the way I build apps these days is to just serve static files over HTTP, and do all the dynamic stuff over WebSocket, which would sidestep all these issues. You mean you have a single-paged application and rewrite the underlying page asynchronously? How do you deal with needing to load different Javascript files per page? I guess you could simply load all the JS files all your pages would ever need, but I assume you do something a little more sophisticated. Thanks, Gili The way you did it was with what I call a one shot cookie. A project I worked on I did a solution where sessionStorage was used to keep a token and a cookie was set via javascript and thus sent along with the request to the server which then tells the browser to delete the cookie in the reply. If the token needs updating then the server can send a one shot cookie to the browser, the javascript will then apply the needed changes to generate a new token (maybe a new salt or nonce is given) and then delete the cookie. Also, this form of cookie use does not fall under the cookie law in Europe AFAIK as it's part of a login mechanism so no need to show those annoying this site/page uses cookies box or warning. Using sessionStorage, and cookies to pass info to/from the server is my new preferred way as you can control how often the cookies are sent and to what part of the site. The solution is not as elegant as I'd like it though. One issue is you can't set the timeout for a cookie (sent from the server) to 0 or 1 sec or similar as the browser could delete the cookie before your javascript can get the data from it. In the other direction the issue is reliably deleting the cookie after it has been sent (sometimes one can use POST requests and avoid this part, but that may not always be practical). Looking at http://stackoverflow.com/questions/26556749/binding-tab-specific-data-to-an-http-get-request the solution you ended up with is very similar to what I ended up doing, I'm not aware of any better way to do this (yet). Regards, Roger. Hi Roger, Did you also use a URL parameter to indicate which cookie the server should look in? I think my solution is problematic in that I have to go through GetTabId.html on page load (which looks ugly) and even worse I recently discovered that View Source does not work because the browser re-sends the request without the tabId parameter (which I stripped to make the URL shareable). I feel like the ideal solution is within an arm's reach but I can't get there. Please describe your approach in more detail on http://stackoverflow.com/q/26556749/14731 so we can learn for each. Thanks, Gili
Re: [whatwg] Modifying the URL inside beforeunload event
On 2014-11-15 03:07, cowwoc wrote: On 14/11/2014 8:56 PM, Roger Hågensen wrote: Did you also use a URL parameter to indicate which cookie the server should look in? I think my solution is problematic in that I have to go through GetTabId.html on page load (which looks ugly) and even worse I recently discovered that View Source does not work because the browser re-sends the request without the tabId parameter (which I stripped to make the URL shareable). What I did was to use a one shot cookie, a request was only ever made by user interaction. The server basically get a token cookie and a id cookie. the server the responds and set the cookies for deletion. There is only ever one token and one id cookie sent, re-using the cookie names are not an issue. Now if each tab automatically makes requests then that is a different issue and in that case using POST instead of GET is advised, in that case you only ever have to send cookies from the server and not to the server. Please describe your approach in more detail on http://stackoverflow.com/q/26556749/14731 so we can learn for each. Don't have an account there, sorry. Regards, Roger. -- Roger Rescator Hågensen. Freelancer - http://www.EmSai.net/
Re: [whatwg] Modifying the URL inside beforeunload event
(pushing this to the top of the queue by request) On Sun, 2 Nov 2014, cowwoc wrote: I would like to bringhttps://code.google.com/p/chromium/issues/detail?id=428583 to your attention. Quoting comment #9: I believe this is a corner case that is not adequately described. I was imagining adding a clause somewhere around step 8 inhttps://html.spec.whatwg.org/multipage/browsers.html#unloading-documents:beforeunloadevent http://html.spec.whatwg.org/multipage/browsers.html#unloading-documents:beforeunloadevent. Specifically, clarifying what the behavior should be if an event handler modifies the url. I believe I have a legitimate use-case (described in comment #9) for needing to change the URL in beforeunload. I am open to alternatives that allow me to achieve the same end-result, but I have not found any good solutions to date. I don't really understand what's unclear here. Can you elaborate? As far as I can tell this is one of the better defined interactions, since the unload algorithm and the pushState algorithm are pretty specific. Generally speaking, though, for your use case you should just use sessionStorage rather than cookies. That's what sessionStorage is for. If you don't want the tabId to be shared, you shouldn't put it in the location bar in the first place -- removing it from the history is too late, because people copy and paste URLs from the location bar while the page is up. You could replaceState() during page load, but I would generally much more recommend sessionStorage for this purpose. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Modifying the URL inside beforeunload event
On 13/11/2014 12:21 AM, Ian Hickson wrote: (pushing this to the top of the queue by request) On Sun, 2 Nov 2014, cowwoc wrote: I would like to bring https://code.google.com/p/chromium/issues/detail?id=428583 to your attention. Quoting comment #9: I believe this is a corner case that is not adequately described. I was imagining adding a clause somewhere around step 8 inhttps://html.spec.whatwg.org/multipage/browsers.html#unloading-documents:beforeunloadevent http://html.spec.whatwg.org/multipage/browsers.html#unloading-documents:beforeunloadevent. Specifically, clarifying what the behavior should be if an event handler modifies the url. I believe I have a legitimate use-case (described in comment #9) for needing to change the URL in beforeunload. I am open to alternatives that allow me to achieve the same end-result, but I have not found any good solutions to date. I don't really understand what's unclear here. Can you elaborate? As far as I can tell this is one of the better defined interactions, since the unload algorithm and the pushState algorithm are pretty specific. Hi Ian, I wish I could invite the chromium committer (from comment #9) to join this conversation. Unfortunately I am unable to look up his email address (I fill out the captcha but the system still refuses to divulge the email address). In any case, the question seems to be whether history.replaceState() should be honored in beforeunload. Individually, each one is very well defined, but I don't see any discussion of what should happen when the two are used together. Are you saying that history.replaceState() should succeed or fail in this case? Generally speaking, though, for your use case you should just use sessionStorage rather than cookies. That's what sessionStorage is for. If you don't want the tabId to be shared, you shouldn't put it in the location bar in the first place -- removing it from the history is too late, because people copy and paste URLs from the location bar while the page is up. You could replaceState() during page load, but I would generally much more recommend sessionStorage for this purpose. Using sessionStorage alone wouldn't work because the goal of this exercise is to send the server a different authentication token per browser tab. I can store these tokens in the sessionStorage (in fact, I do) but that's not enough because the browser still needs to send the token to the server with each request. I hope this clarifies my dilemma. http://stackoverflow.com/a/26901232/14731 explains how my current implementation works. It's very lengthy and ugly so I'm more than happy to entertain alternatives. Thanks, Gili
Re: [whatwg] Modifying the URL inside beforeunload event
Hi Michal, I'm relatively new to this mailing list. How do proposals make their way to action items here? Thanks, Gili On 02/11/2014 4:53 PM, Michal Zalewski wrote: It's probably OK to replace the URL of the previous page if it otherwise doesn't interfere with the ongoing navigation. The old attacks predated the pushState / replaceStates API altogether. /mz On Sun, Nov 2, 2014 at 1:43 PM, cowwoc cow...@bbs.darktech.org wrote: On 02/11/2014 12:28 PM, Michal Zalewski wrote: I believe I have a legitimate use-case (described in comment #9) for needing to change the URL in beforeunload. I am probably at least partly to blame for the browsers not letting you do that - I reported several onbeforeunload attacks some 8 years ago. Sorry!:-) In general, there is a security-driven desire to prevent a website from trapping visitors and not allowing them to navigate away. This not just a matter of nuisance attacks, but when employed in a clever way, can be a powerful tool for phishing if you can convince the user to type in a known URL and then spoof the page transition. If we end up allowing navigation to be aborted or modified from within unload-related events, we need to keep that in mind. /mz Hi Michal, I had a feeling this was security related :) Correct me if I'm wrong, but don't the attacks you mentioned rely upon access to history.back()/forward()? Would it be safe to allow history.replaceState() while forbidding the other two? Meaning, we would allow a page to rewrite its own address but not other pages' addresses. Gili
Re: [whatwg] Modifying the URL inside beforeunload event
On Tue, Nov 4, 2014 at 3:34 PM, cowwoc cow...@bbs.darktech.org wrote: I'm relatively new to this mailing list. How do proposals make their way to action items here? I recommend studying https://wiki.whatwg.org/wiki/FAQ In this particular case Ian will get back to you. -- https://annevankesteren.nl/
Re: [whatwg] Modifying the URL inside beforeunload event
On 04/11/2014 9:38 AM, Anne van Kesteren wrote: On Tue, Nov 4, 2014 at 3:34 PM, cowwoc cow...@bbs.darktech.org wrote: I'm relatively new to this mailing list. How do proposals make their way to action items here? I recommend studying https://wiki.whatwg.org/wiki/FAQ In this particular case Ian will get back to you. Got it. Thanks Anne :) Gili
[whatwg] Modifying the URL inside beforeunload event
Hi, I would like to bringhttps://code.google.com/p/chromium/issues/detail?id=428583 to your attention. Quoting comment #9: I believe this is a corner case that is not adequately described. I was imagining adding a clause somewhere around step 8 inhttps://html.spec.whatwg.org/multipage/browsers.html#unloading-documents:beforeunloadevent http://html.spec.whatwg.org/multipage/browsers.html#unloading-documents:beforeunloadevent. Specifically, clarifying what the behavior should be if an event handler modifies the url. I believe I have a legitimate use-case (described in comment #9) for needing to change the URL in beforeunload. I am open to alternatives that allow me to achieve the same end-result, but I have not found any good solutions to date. Thank you, Gili
Re: [whatwg] Modifying the URL inside beforeunload event
I believe I have a legitimate use-case (described in comment #9) for needing to change the URL in beforeunload. I am probably at least partly to blame for the browsers not letting you do that - I reported several onbeforeunload attacks some 8 years ago. Sorry!:-) In general, there is a security-driven desire to prevent a website from trapping visitors and not allowing them to navigate away. This not just a matter of nuisance attacks, but when employed in a clever way, can be a powerful tool for phishing if you can convince the user to type in a known URL and then spoof the page transition. If we end up allowing navigation to be aborted or modified from within unload-related events, we need to keep that in mind. /mz
Re: [whatwg] Modifying the URL inside beforeunload event
On 02/11/2014 12:28 PM, Michal Zalewski wrote: I believe I have a legitimate use-case (described in comment #9) for needing to change the URL in beforeunload. I am probably at least partly to blame for the browsers not letting you do that - I reported several onbeforeunload attacks some 8 years ago. Sorry!:-) In general, there is a security-driven desire to prevent a website from trapping visitors and not allowing them to navigate away. This not just a matter of nuisance attacks, but when employed in a clever way, can be a powerful tool for phishing if you can convince the user to type in a known URL and then spoof the page transition. If we end up allowing navigation to be aborted or modified from within unload-related events, we need to keep that in mind. /mz Hi Michal, I had a feeling this was security related :) Correct me if I'm wrong, but don't the attacks you mentioned rely upon access to history.back()/forward()? Would it be safe to allow history.replaceState() while forbidding the other two? Meaning, we would allow a page to rewrite its own address but not other pages' addresses. Gili
Re: [whatwg] Modifying the URL inside beforeunload event
It's probably OK to replace the URL of the previous page if it otherwise doesn't interfere with the ongoing navigation. The old attacks predated the pushState / replaceStates API altogether. /mz On Sun, Nov 2, 2014 at 1:43 PM, cowwoc cow...@bbs.darktech.org wrote: On 02/11/2014 12:28 PM, Michal Zalewski wrote: I believe I have a legitimate use-case (described in comment #9) for needing to change the URL in beforeunload. I am probably at least partly to blame for the browsers not letting you do that - I reported several onbeforeunload attacks some 8 years ago. Sorry!:-) In general, there is a security-driven desire to prevent a website from trapping visitors and not allowing them to navigate away. This not just a matter of nuisance attacks, but when employed in a clever way, can be a powerful tool for phishing if you can convince the user to type in a known URL and then spoof the page transition. If we end up allowing navigation to be aborted or modified from within unload-related events, we need to keep that in mind. /mz Hi Michal, I had a feeling this was security related :) Correct me if I'm wrong, but don't the attacks you mentioned rely upon access to history.back()/forward()? Would it be safe to allow history.replaceState() while forbidding the other two? Meaning, we would allow a page to rewrite its own address but not other pages' addresses. Gili