*Really* deleting cookies with javascript - javascript

The way to delete cookies in javascript is to set the expiry date to be in the past. Now this doesn't actually delete the cookie, at least in Firefox. It just means the cookie will be deleted on browser close.
This is a problem for us: we have a product that involves archiving web pages from potentially many sites, with all this content stored on our server. And to make sure that pages render properly we include all js as well. However often cookies are set by js, and given that the page is cached on our server, these cookies are set under our domain.
So over time cookies from dozens of archived sites build up under our domain. And eventually the Cookie header exceeds the max content length, resulting in an HTTP 400 error code.
And because our clients are mostly in corporate environments they never reboot their machines or close their browsers: they can be left on for months. So this "soft" delete doesn't work, at least not reliably.
Is there any way to physically remove cookies intra-session in javscript? Or alternatively, is there any way to stop them being set?

It's not possible. Period. I've been struggling with this for several weeks without finding a solution.
Whoever invented the cookie getter/setter should be %insert_painful_punishment_here%.
Particularly Internet Exploder is a beast when it comes to deleting cookies. I can't remember the exact issue, but I think it involved https and cookie names containing ;.
All I can offer is a workaround: Send a response body with your 400 response, something like 'please restart your browser'.

In addition to setting the expiration in the past, set the value to an empty string. This will at least reduce the size of the cookie immediately.
I would think that cookies should be deleted immediately in all browsers. For example, when I log out of a website, Firefox does not require me to close my browser to delete the cookie that shows that I am logged into the site. If this isn't happening, I suggest you look into Firefox bugs and possibly open a new one with them.
In the meantime, I'd look at my web server and see if it is possibly to set the max content length to something higher than it already is.

You could overwrite the cookie with a new one.

"It is because we are NOT using iframes that we have this issue. The cached page is being rendered by our server, so any cookies get set under our domain." --OP
If you have no control over the javascript that is setting the cookies (which seems extremely odd, why do you not have control?), you can constantly read and empty the cookie, dumping the data to another larger database (preferably server-side, or perhaps HTML5 client storage).

Related

Is there a way to clear HSTS without an SSL cert?

Recently, I switched the server for my site, and I managed to lose the decrypted SSL key, and I cannot remember the password for the encrypted one.
It turned out that the server had set HSTS on, and now many visitors are unable to load the pages since I don't have a valid SSL cert, and their browsers refuse to connect via http due to the HSTS.
So, I need a way to disable that HSTS from their browsers. Asking them to clear browsing data is a no-go, but I was wondering if I could make a firefox/chrome compatible javascript to clear it. (The script would be on a different domain)
I've been digging around a bit, but haven't found much info on how I should approach the problem, if it is even possible. All other suggestions are welcome too.
HSTS is there to make a tradeoff: you take responsibility to from now and forever provide a secure SSL connection which the browser can count on, which will cause the browser to refuse anything but an SSL connection to your domain. It puts an additional burden on you, but increases security for your visitors.
The browser stores this preference in an internal database which cannot be cleared by any website. If it'd be possible for any site to simply revoke this preference via Javascript, the whole system would be pointless.
You'll have to manually clear the database and/or remove that specific entry. Every browser does it differently, see http://classically.me/blogs/how-clear-hsts-settings-major-browsers for an overview.
The real solution:
Install a valid cert
Get people to visit your site
Send a new header
These days, getting a valid cert is free, or costs less than a sandwich ($8 or so).

Are there any drawbacks to using localStorage instead of Cookies?

On my previous websites, I used to use a cookie to display a pre-home page only on the first visit. That worked great (see for example here), but using cookies is not so trendy today, so I want to avoid it as much as possible.
Now, my new website projects almost always have pre-home launched via javascript (showing a modalbox), so I don't need to do any action on the server side. I'm considering to use HTML5 localStorage instead of cookies, with a fallback on cookies if the browser does not have localStorage. Is this a good idea? What is the impact in terms of usability, privacy protection and website performance?
Using localStorage will improve usability for users that have disabled cookies. But I know that some HTML5 features are only opt-in (like geolocalisation) in some browser. Is there any restriction like that for localStorage on any browser ? Is there any case where I will get a JS error if localStorage is available but deactivated for my site ?
Usability
The user will not know if you are using localStorage or a cookie. If a user disable cookies, localStorage will not work either.
Performance
There is no noticeable speed difference between the two methods.
sessionStorage
sessionStorage is only for that browser tab's session. If you close the tab, the session will be lost and the data will be lost too, it's similar to a session variable on any backend language.
localStorage
localStorage will be available for any tab or window in the browser, and will exist until it is deleted by the user or the program. Unlike a cookie, you cannot setup expiration. localStorage has a much larger storage limit as well.
Your Questions
You are not using this data server side, so you don't need a cookie. localStorage is never sent to the server unlike a cookie.
If the user disables the cookies, localStorage will not work either.
Fallback Example
You can use a Modernizr to verify if localStorage is available and if not, use store a cookie instead.
if (Modernizr.localstorage) {
// supports HTML5 Storage :D
} else {
// does not support HTML5 Storage :(
}
You can also forego Modernizr and use the check typeof Storage !== 'undefined'.
Comparing LS vs cookies is comparing apples to oranges.
Cookies and LS are completely different things for different purposes. LS is a tool that allows your client (javascript code) to store its data locally, without transmitting it to the server. Cookies is a tool for the client-server communication. The whole point of cookies is to be sent over with each request.
In the past cookies were often abused to emulate the local storage, just because it was the only possibility for a javascript application to write anything to the client's hard drive. But generally LS is not a replacement for cookies, so if you need something that both client and server should read and write, use cookies, not LS.
One point to add, unlike cookie normally shared cross protocol, the storages stick to same-origin policy. As a consequence sites share the same domain but hosted on different protocol do not share the stored data.
Say if your website need to work across http and https. For example, when user clicked the "purchase link" they will land on https secured checkout, then the checkout won't be able to retrieve the data previously stored on http site, even when they share the same domain.
It doesn't look easy for the server to read the localStorage. That may come in handy though, knowing your data is all client-side, making it safe from sniffing.
Cookies can't be written over, only added to and read:
alert(document.cookie);
document.cookie = "nope";
alert(document.cookie);
The one thing I didn't like about using 'localstorage' is that all your script code is visible when you 'inspect' (F12) the page. Go into SOURCES and from the left panel locate your website name and open it. All your code within the tags is totally visible. So if you've got some sensitive values on display, liked hashed passwords, special words, they all there for the world to see. I'm not sure what the world will do with this info, but it's not very secure.

Is there a reliable way to log a user out when the browser is closed?

I am looking for a reliable way to log out a user or abandon their session when the browser is closed. Is there a way to do this with tabbed browsers?? Any suggestions are appreciated. Thanks!
There is no reliable way to do this immediately when the client closes the browser. There's the beforeunload event, but even then, when you fire an ajax request during this event, it's not guaranteed to ever reach the server. Still then, you've a problem with multiple browser tabs.
Most reliable way is to have a relatively short session timeout in the server side (e.g. 1 minute) and introduce an ajaxbased heartbeat on the client side (e.g. every 30 seconds) to keep the session alive.
There may be better ways depending on the sole functional requirement for which you thought that this is the solution. For example, if your actual intent is to restrict all logins to 1 per registered user, then you'd better collect all logins and the associated sessions and then compare this on each login and invalidate the earlier session if any present. This way it'll work as well on clients with JS disabled.
If you aren't using cookies to preserve your users' login information, it should log them out when they close the browser, because any session cookies should be killed when the browser closes.
Obviously this isn't always the case (see here for an example of Firefox preserving login information after logging out) because "session restore" features we now blur the line between what is considered a "single browser session". (Personally, I think this should be classified as a bug, but that is only my opinion).
There are two possible techniques. The first would be (as yojimbo87 mentions before me) to use web sockets to keep a connection between client and server, and when the socket closes, kill the session. The issue here is that web sockets support is limited, and certainly not possible on anything other than bleeding edge browsers (FF4, Chrome, IE9, etc).
An alternative could be to use AJAX to constantly poll the server to tell it that the page is still being viewed, so if, for example, you send a keep-alive request via AJAX every 30 seconds, you'd store the timestamp of the request in the session. If the user then comes back to the page and the time difference between the current request and the last request is more than say... 45 seconds (accounting for latency), you'd know that the user closed their browser and need to log in again.
In both of these situations, there is however a fatal flaw, and that is that they rely on JavaScript. If the user doesn't have JavaScript enabled, you'd end up ruining the user experience with constant login prompts, which is obviously a bad idea.
In my opinion, I think its reasonable to simply rely on session cookies being deleted by the browser when the user closes the browser window, because that is what they are supposed to do. You as a developer can't be blamed when the client browser performs undesirable behaviour, since its entirely out of your hands, and there's no functional workaround.
A feasible technique would be to use AJAX to send keep-alive requests to your servers quite often — e.g. every one minute. Then you could abandon a session as soon as a keep-alive (or a few in sequence) is not received as expected.
Otherwise, there's no reliable way to achieve that. Since there's not a persistent connection between the browser and the server you can't detect situations that are out-of-control of any JavaScript code you might have running in the browser. For example, when there's a network failure you might want to close the session as well even though the browser's window is still opened. Hence, to make the system robust enough, you should detect network outages as a “side-effect” of the keep-alive mechanism from the browser (e.g. like Gmail does it).
Unless you are using WebSockets or some kind of long polling for each tab which tracks the connection with client in "real time", you will probably have to wait until the session is timed out on the server side.
You can do this via a combination of Jquery,Ajax and PHP
The Jquery
function updatestatusOFF(){
// Assuming we have #shoutbox
$('#connection').load('connection.php?user=<?php echo $_SESSION['username']; ?>&offline=true');
}
The before unload script
<script>window.onbeforeunload = function() { return updatestatusOFF(); }</script>
and the php you would have to write yourself which i'm more then certain you can do.
it isn't the most reliable but it's the easiest way to implement that. if you want real time reporting .. look into comet

Javascript Login and Get Information with Post, No Cookies?

so right now I'm writing a Windows 7 Gadget using Javascript (w/HTML) that will grab some information from a page that it needs to log in to. So I have apparently gotten the Post statement to work over the https domain, because now I get a page in the responseText telling me I need to have cookies enabled. Right now I use a ServerXMLHTTP object to make a request, which is comparable to using an XMLHttpRequest object. I don't know that cookies CAN be enabled in a Windows 7 Gadget, so I'm looking for an answer on whether or not they can be, some kind of work around if possible, or some other avenue to take for getting the solution.
Windows Desktop Gadgets do support cookies, but they only persist for the life of the sidebar.exe process — once that closes all cookies are forgotten. However, I did just check and MSXML2.ServerXMLHTTP doesn't store cookies by default, I'm not sure if there are any options you can enable.
Is there some reason you're using ServerXMLHttp over XMLHttpRequest? If you use XMLHttpRequest the site should work fine.
I figured I'd come tie up this loose end, I figured out to post to the server by setting a randomly generated cookie of valid length and setting that as the requestheader for the SXH request. Also necessary was to set the address of the server as the host of the SXH request. At that point it was a matter of posting to the correct url and then sending a valid query.

Best practice use sam AJAX in multiple browser windows?

I am developing a website that has some sort of realtime update.
Now the website is generated with a javascript variable of the current ID of the dataset.
Then in an interval of some seconsd an AJAX call is made passing on the current ID, and if theres something new the server returns it along with the latest ID which is then updated in the javascript.
Very simple, but here comes the Problem.
If the user opens the same page multiple times, every page does this AJAX requests which produces heavy serverload.
Now I thought about the following approach:
The website is loaded with a javascript variable of the current timestamp and ID of the current dataset.
My desired refresh interval is for example 3 seconds.
In the website an interval counter counts up every seconds, and everytime the timestamp reaches a state where (timestmap % 3===0) returns true, the content is updated.
The link looks like http://www.example.com/refresh.php?my-revision=123&timestamp=123456
Now this should ensure that every browser window calls the same URL.
Then I can turn on browser level caching.
But I don't really like this solution.
I would prefer adding another layer of data sharing in a Cookie.
This shouldn't be much of a problem, I can just store every request in a cookie named by timestamp and data revision with a TTL of 10 seconds or so and check for its exitence first.
BUT
The pages will do the request at the same time. So the whole logic of browser caching and cookie might not work because the requests occour simultanously and not one after another.
So I thought about limiting the current connections to 1 server side. But then I would need at least an extra vhost, because I really dont want to do that for the whole page.
And this lets me run into problems concerning cross-site policies!
Of course there are some super complicated load balancing solutions / server side solusions bound to request uri and ip adress or something but thats all extreme overkill!
It must be a common problem! Just think of facebook chat. I really don't think they do all the requests in every window you have open...
Any ideas? I'm really stuck with this one!
Maby I can do some inter-window Javascript communication? Shouldnt be a problem if its all on the same domain?
A thing I can do of course is server side caching. Which avoids at least DB Connections and intensive calculations... but it still is an request which I would like to avoid.
You might want to check out Comet and Orbited .
This is best solved with server push technology.
The first thing is: Do server-side caching anyway, using Memcache or Redis or whatever. So you're defended against three machines doing the requests. But you knew that.
I think you're onto the right thing with cookies, frankly (but see below for a more modern option) — they are shared by all window instances, easily queried, etc. Your polling logic could look something like this:
On polling interval:
Look at content cookie: Is it fresher than what you have? If so, use it and you're done.
Look at status cookie; is someone else actively polling (e.g., cookie is set and not stale)? If yes, come back in a second.
Set status cookie: I'm actively polling at (now).
Do request
On response:
If the new data is newer than the (possibly updated) contents of the content cookie, set the content cookie to the new data
Clear status cookie if you're the one who set it
Basically, the status cookie acts as a semaphore indicating to all window instances that someone, somewhere is on the job of updating the content.
Your content cookie might contain the content directly, or if your content is large-ish and you're worried about running into limits, you could have each page have a hidden iframe, each with a unique name, and have your Ajax update write the output to the iframe. The content cookie would publish the name of the most up-to-date iframe, and other windows seeing that there's fresh content could use window.open to get at that iframe (since window.open doesn't open a window if you use the name of an existing one).
Be alert to race conditions. Although JavaScript within any given page is single-threaded (barring the explicit use of web workers), you can't expect that JavaScript in the other windows is necessarily running on the same thread (it is on some browsers, not on others — heck, on Chrome it's not even the same process). I also don't know that there's any guarantee of atomicity in writing cookies, so you'll want to be vigilant.
Now, HTML5 defines some useful inter-document communication mechanisms, and so you might consider looking to see if those exist and using them before falling back on this cookie approach, since they'll work in modern browsers today but not in older browsers you're probably having to deal with right now. Still, on the browsers that support it, great!
Web storage might also be an option worth investigating as an aspect of the above, but your clients will almost certainly have to give your app permissions and it's also a fairly new thing.

Categories

Resources