Deleting cookies with JavaScript in Firefox extension - javascript

I have searched a lot for deleting all or a specific cookie with JavaScript.
There are lots of posts that say its not possible 100%, or you can not delete cookies with HttpOnly flag. Then the question is how the Cookies Manager+ Firefox extension can delete cookies with JavaScript? Or how the Delete All Cookies From JavaScript Chrome extension lets programmers delete cookies by sending postMessage to his extension?
I am developing a Firefox extension and need to delete some cookies from a website.
How do I delete cookies in a Firefox extension?

As Alexander O'Mara mentioned in a comment, Chrome and Firefox JavaScript extensions run in a context that has higher privileges than JavaScript that is included on webpages. At that higher privilege level they are permitted to make changes to cookies. Your confusion probably is that you are reading webpages that discuss what is possible for JavaScript that is running from a webpage.
While I have not tested it, the following code appears to do what you want:
var {Cc, Ci} = require("chrome");
function DeleteAllCookiesForDomain( domain ) {
var cookieManager = Cc["#mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
var iter = cookieManager.enumerator;
var cookie_count = 0;
while (iter.hasMoreElements()) {
var cookie = iter.getNext();
if (cookie instanceof Ci.nsICookie) {
if (domain.indexOf(cookie.host.toUpperCase()) != -1) {
cookieManager.remove(cookie.host, cookie.name, cookie.path, false);
cookie_count++;
}
}
}
return cookie_count;
};
The above code is slightly modified from code found in How do I delete cross site cookies with Firefox 22+ extension?.
However, the above code is inefficient as it iterates over all cookies, not just those from the domain you are interested in deleting. The following uses the nsICookieManager2 interface to iterate only over those cookies for the domain which you are deleting:
//For SDK
var {Cc, Ci} = require("chrome");
var cookieManager = Cc["#mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
//*/
/*//For restartless/bootstrap/overlay
Components.utils.import("resource://gre/modules/Services.jsm");
var cookieManager = Services.cookies;
//*/
function DeleteAllCookiesForDomain( domain ) {
var iter = cookieManager.getCookiesFromHost(domain);
var cookie_count = 0;
while (iter.hasMoreElements()) {
var cookie = iter.getNext();
if (cookie instanceof Ci.nsICookie) {
cookieManager.remove(cookie.host, cookie.name, cookie.path, false);
cookie_count++;
}
}
return cookie_count;
};

Just use browsingData API I found it very friendly and easy to use
In your background script
var removalOptions = {hostnames: ['example.com', 'www.example.com']};
var dataTypeSet = {cookies: true}; // , indexedDB: true, localStorage:true
browser.browsingData.remove(removalOptions , dataTypeSet);
Note: I used "browsingData" and "storage" permissions in the mainfest.json file of the extension

Related

Serial Port communication in Chrome

I have a legacy application which is making use of ActiveX control for serial communication. This is rightly communicating in IE.
Since ActiveX is IE specific technology obviously it will not run in Chrome or other browser
So I don't want to disturb the IE functionality and thought of introducing browser specific function as below.
$(document).ready(function(e){
var isIEBrowserFlag = true;
if(isIEBrowserFlag)
{
var obj = new ActiveXObject("MSCommLib.MSComm");
obj.CommPort = commPort;
obj.RThreshold = thresHold;
obj.Settings = settings;
obj.PortOpen = true;
obj.DTREnable = true;
obj.Output = "test";
obj.PortOpen = false;
//other stuff
}
else
{
//chrome
}
//sendBagToPrinter(obj);
});
On googling I came to know about jQuery.parseXML() but how do I implement the same functionality as of IE in Chrome using $.parseXML()
Similar other plugins such as juart were tried, but not fitting my requirement.
chrome.serial API provides access to client serial ports, but from a Chrome App.
My suggestion, for future support, use/write some kind of server for serial device and connect from browser to server via a json type communication. See https://github.com/johnlauer/serial-port-json-server

Chrome ignores certificate pinning from extension

I am creating a secure chrome extension that is supposed to safely connect to an external https url that i do not own and that doesnt utilize certificate pinning itself. Using HPKP, i want to pin the certificate in the browser extension to verify the host is legit.
I did some research where its claimed that this is not possible apart from calling chrome via command line. It was hard finding a lot of informations about HKPK for chrome (extensions)
Using webRequest & webRequestBlocking permissions i tried to intercept the response header. The theory is that if i can add the HPKP header into the response header, i can simulate the browser filtering future traffic from this header. I do this with the code below.
chrome.webRequest.onHeadersReceived.addListener(function(details) {
//86400 = 1 day to prevent lockout on missing update
var addHeader = [
{name:"Public-Key-Pins", value:'max-age=30; pin-sha256="+sCGKoPvhK0bw4OcPAnWL7QYsM5wMe/mn1t8VYqY9mM="; pin-sha256="bumevWtKeyHRNs7ZXbyqVVVcbifEL8iDjAzPyQ60tBE="'},
{name:"Strict-Transport-Security", value:"max-age=86400"}
];
for(var i=0;i<details.responseHeaders;i++) {
var existHeader = details.responseHeaders[i];
for(var o=0;o<addHeader.length;o++) {
var writeHeader = addHeader[o];
if(existHeader.name.toLowerCase() == writeHeader.name.toLowerCase()) {
details.responseHeaders[i].value = writeHeader.value;
addHeader[o].written = true;
}
}
}
for(var i=0;i<addHeader.length;i++) {
var writeHeader = addHeader[i];
if(!writeHeader.hasOwnProperty("written")) details.responseHeaders.push({name:writeHeader.name, value:writeHeader.value});
}
return {responseHeaders: details.responseHeaders};
}, {urls: ["<all_urls>"]}, ["blocking","responseHeaders"]);
chrome.webRequest.onResponseStarted.addListener(function(details) {
console.log(details);
}, {urls: ["<all_urls>"]}, ["responseHeaders"]);
The SHA256 hashes are random certificates found online, and when i call a website i expect the browser to block the request as long as its an https url (as RFC ignores http ones). Sadly, nothing happens at all, but the console returns that the data did get indeed attached.
My question is: Did i do something wrong at another place, or is there any other way to have my browser extension verify its talking to the correct host?

Chrome - Finding which other extensions are using a particular permission

I am developing an extension that requires proxy permissions. For that, I also need to block out or atleast detect any other extension currently active with proxy permissions. How do I do that?
It's heavy-handed, but you can use Management API.
chrome.management.getAll(function(details){
var proxyIds = [];
for(var i in details){
if(details[i].permissions.filter(function(el){return el == "proxy"}).length > 0){
proxyIds.push(details[i].id);
}
}
/* use proxyIds */
});

Is it possible to evaluate whether the clients browser is in incognito mode? [duplicate]

I'm building an extranet for a company paranoid about security. They want to make sure that (among other things) their users are browsing the site with the Private Browsing mode switched on in their web browser so that no cookies or history is kept.
I found only this
http://jeremiahgrossman.blogspot.com/2009/03/detecting-private-browsing-mode.html
and
https://serverfault.com/questions/18966/force-safari-to-operate-in-private-mode-and-detect-that-state-from-a-webserver
The ideal solution would use no or minimal javascript. Would attempting to set a unique cookie work for all browsers and platforms? Anyone done this before?
thanks!
update
http://crypto.stanford.edu/~collinj/research/incognito/ uses the CSS visited technique of the browser fingerprinters mentioned by other posters- thanks for the hints.
I like it because it is small and elegant, but still want to be able to do it without javascript if possible.
Update June 2019
Google is removing the ability to detect Private Browsing Mode permanently in Chrome 76 onwards. So, if you're wanting to detect private browsing it's now impossible (unless you find a way to do it that Google hasn't found). The ability to detect private browsing mode has been acknowledged as a bug and was never intended.
To anyone else coming across this question, please note as of 2014, there is no reliable or accurate way to detect if someone is browsing in an incognito/private/safe browsing mode through Javascript or CSS. Previous solutions that once worked like the CSS history hack have since been rendered unusable by all browser vendors.
There should never be a situation where needing to detect private browsing mode on a normal day-to-day website is ever needed. People are choosing to browse anonymously and or not anonymously for their own reasons.
Browsers like Chrome and Firefox do not disable functionality like localStorage any more. They simply namespace it in a temporary location to prevent websites that use it from erroring out. Once you're finished browsing, the namespace is erased and nothing is saved. If you are testing for localStorage support regardless of mode, it will always return true for browsers that support it.
Other means of detecting private mode in Chrome specifically have been completely patched and will no longer work.
If it is required internally by a company, you should develop a browser plugin. Chrome and Firefox, in particular, expose internal API's which allow plugins to check if the user is in private browsing/incognito mode and action accordingly. It cannot be done outside of a plugin.
Here's an easier way to do detect privacy mode. This works in Safari only. I created it because a web app I am developing uses localStorage. LocalStorage is not available in Safari when in privacy mode, thus my app will not work.
On page load, run the script below. It shows an alert box if we cannot use localStorage.
try {
// try to use localStorage
localStorage.test = 2;
} catch (e) {
// there was an error so...
alert('You are in Privacy Mode\nPlease deactivate Privacy Mode and then reload the page.');
}
Current state
Google Chrome has developed further and leaves no more space for detection when using incognito mode. Same might apply for other browsers.
Old solutions (might partially work)
It is possible to detect enabled private browsing modes for the majority of used browsers. This includes Safari, Firefox, IE10, Edge and Google Chrome.
Firefox
When the private browsing mode of Firefox is enabled, the IndexedDB throws an InvalidStateError because it is not available in private browsing mode.
To very if that:
var db = indexedDB.open("test");
db.onerror = function(){/*Firefox PB enabled*/};
db.onsuccess =function(){/*Not enabled*/};
Safari
For Safari, the key is the local storage service. It is disabled in privacy mode. So try to access it and use a try-catch clause.
The following method works on both, OSX and iOS devices. Credits for this method are going to this question and answer
var storage = window.sessionStorage;
try {
storage.setItem("someKeyHere", "test");
storage.removeItem("someKeyHere");
} catch (e) {
if (e.code === DOMException.QUOTA_EXCEEDED_ERR && storage.length === 0) {
//Private here
}
}
IE10/Edge
Internet Explore is even going to disable the IndexedDB when in privacy mode. So check for existence. But that's not sufficient enough, because older browsers maybe don't even have an IDB. So do another check, e.g. for events that only IE10 and subsequent browser have/trigger. A related question on CodeReview can be found here
if(!window.indexedDB && (window.PointerEvent || window.MSPointerEvent)){
//Privacy Mode
}
Chrome
Update: This doesn't work since Chrome 76 (thanks to #jLynx)
Chromes Incognito mode can be verified by the file system. A great explanation can be found here on SO
var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
if (!fs) {
console.log("FS check failed..");
return;
}
fs(window.TEMPORARY, 100, function (fs) {}, function (err) {
//Incognito mode
});
update on safari
Safari (release v29) patched localstorage so that you can no longer use it for detection.
I saw one other solution that tries to save blob/files in indexedDB and that will reject with an error saying that it can't store fils when surfing in private mode.
but there is a new / easier method with the new whatwg/fs
navigator.storage.getDirectory().then(root => {
console.log('not private')
}, err => {
console.log('private')
})
Chrome 83 arrives with redesigned security settings, third-party cookies blocked in Incognito by default!
So this one is easy, create a iframe to a third party site, have it send a postMessage back notifying you if navigator.cookieEnabled is true or false. Ofc users have the option to disable third party cookie as well. So i tested and disabled 3th party cookies in the settings. But it still said cookie was enabled on third-party iframes using navigator.cookieEnabled. it only became disabled once i used Incognito - perhaps a bug?
new Promise((rs, rj, m = new MessageChannel(), d = document, i = d.createElement('iframe')) => {
i.src = 'https://httpbin.org/base64/PHNjcmlwdD5vbm1lc3NhZ2UgPSBlID0+IGUuZGF0YS5wb3N0TWVzc2FnZShuYXZpZ2F0b3IuY29va2llRW5hYmxlZCk8L3NjcmlwdD4='
i.onload = _ => i.contentWindow.postMessage(m.port1, '*', [m.port1], m.port2.onmessage = e => i.remove(rs(e.data)))
i.hidden = 1
d.body.append(i)
}).then(thirdPartyCookieEabled =>
console.log('Third party cookie enabled:', thirdPartyCookieEabled)
)
You could also probably do it using only js + ajax but didn't want to set up a 2 servers to test it myself. but for this SameSite=none have to be set as well.
res = await fetch('https://httpbin.org/cookies/set?enabled=1', {
credentials: 'include'
})
json = await res.json()
console.log(!!json.cookies.enabled)
Here is my take on detecting private mode
function detectPrivateMode(cb) {
var db,
on = cb.bind(null, true),
off = cb.bind(null, false)
function tryls() {
try {
localStorage.length ? off() : (localStorage.x = 1, localStorage.removeItem("x"), off());
} catch (e) {
// Safari only enables cookie in private mode
// if cookie is disabled then all client side storage is disabled
// if all client side storage is disabled, then there is no point
// in using private mode
navigator.cookieEnabled ? on() : off();
}
}
// Blink (chrome & opera)
window.webkitRequestFileSystem ? webkitRequestFileSystem(0, 0, off, on)
// FF
: "MozAppearance" in document.documentElement.style ? (db = indexedDB.open("test"), db.onerror = on, db.onsuccess = off)
// Safari
: /constructor/i.test(window.HTMLElement) || window.safari ? tryls()
// IE10+ & edge
: !window.indexedDB && (window.PointerEvent || window.MSPointerEvent) ? on()
// Rest
: off()
}
detectPrivateMode(function (isPrivateMode) {
console.log('is private mode: ' + isPrivateMode)
})
edit found a modern, faster, synkronas way to try it in firefox (they don't have service workers in privat mode) similar to ie don't include indexedDB but the test only works in secure sites
: "MozAppearance" in document.documentElement.style ? navigator.serviceWorker ? off() : on()
There's no way for your web page to know, absolutely for sure, that the user is in private browsing mode. Any attempts to check for various browser features will need to change often as security implementations are updated. It may work for some time in some browsers, but not all.
If the company is that concerned about security, I'd suggest rolling your own Firefox or Chromium distribution with locked down privacy settings, and only allowing that custom client to connect to the extranet.
I have built a little library that will work on all major platforms and browsers that I have tested: https://github.com/jLynx/PrivateWindowCheck
You can simply call
isPrivateWindow(function(is_private) {
if(is_private)
alert('Private');
else
alert('Not Private');
});
Many seem to believe that detecting incognito/private mode is no longer possible, and I can assure you that's definitely not true. I have been unable to find any publicly available code that works on 100% of browsers, so I made my own.
As of October 2021 my code is able to detect private browsing modes on Safari 15 (macOS & iOS), Chrome 93, Edge 93, Firefox 93, Internet Explorer 10+, as well as Brave.
I should also note that detecting incognito has legitimate, non-paywall related uses, of which I am using as part of a larger private project. For example, fraudsters often use incognito when conducting credit card fraud. While alone someone filling in a checkout form in incognito doesn't immediately scream fraud, paired with other data points (such as the user using a VPN as well), I would be wary of accepting such an order.
Sites that block access based on whether one is in incognito suck, but I pin that down more to bad site design.
Shameless plug: https://github.com/Joe12387/detectIncognito
I also have a demo available: https://detectincognito.com/
I hope this is helpful.
The localStorage trick is a bug which has been fixed, and it doesn't work anymore in Safari 11.0.
There is an interesting alternative that works in Safari, Opera and Internet Explorer (not Chrome): those browser send a DNT: 1 header (Do Not Track).
It's not 100% reliable because this header can be enabled for normal browsing (it's disabled by default), but it can help to identify privacy-conscious users.
Web browsers behave differently when privacy mode is activated.
On many browsers the caching of resources is limited. It is possible to detect where a browser has been based on their CSS cache. Its possible to conduct this this attack without JavaScript.
The EFF is working on a project to fingerprint browsers. Parts of the browsers fingerprint will be different when privacy mode is activated. Go ahead, try it.
You're not going to block them if they don't have private browsing enabled.
Why have a smart message box at all?
Would attempting to set a unique cookie work for all browsers and platforms? Anyone done this before?
I think the most elegant solution would be to:
Perform a security leak test
If security leak test reveals issue
Tell user to check settings
Suggest privacy mode
Because as you said, not everyone can or needs to enable privacy mode.
I agree with DigitalSeas's sentiment that we should generally not try to detect if the user is in a "private browsing" mode. However, I recently discovered that FireFox now subscribes to a service called "disconnect.me", which provides the url blacklist they use in their "tracking protection" feature. Since disconnect.me blacklists certain social networks (e.g. Facebook's facebook.net), we found that their SDKs would not load in FireFox. Therefore, it seems reasonable that we could try and detect private browsing mode in order to provide a more useful and precise error message to our users.
With that justification out of the way, this gist claims to provide detection for private browsing in major browsers using tricks specific to those browsers. At the time of this writing (the gist may have been updated by the time you read this) the detection logic is as follows:
function retry(isDone, next) {
var current_trial = 0, max_retry = 50, interval = 10, is_timeout = false;
var id = window.setInterval(
function() {
if (isDone()) {
window.clearInterval(id);
next(is_timeout);
}
if (current_trial++ > max_retry) {
window.clearInterval(id);
is_timeout = true;
next(is_timeout);
}
},
10
);
}
function isIE10OrLater(user_agent) {
var ua = user_agent.toLowerCase();
if (ua.indexOf('msie') === 0 && ua.indexOf('trident') === 0) {
return false;
}
var match = /(?:msie|rv:)\s?([\d\.]+)/.exec(ua);
if (match && parseInt(match[1], 10) >= 10) {
return true;
}
return false;
}
function detectPrivateMode(callback) {
var is_private;
if (window.webkitRequestFileSystem) {
window.webkitRequestFileSystem(
window.TEMPORARY, 1,
function() {
is_private = false;
},
function(e) {
console.log(e);
is_private = true;
}
);
} else if (window.indexedDB && /Firefox/.test(window.navigator.userAgent)) {
var db;
try {
db = window.indexedDB.open('test');
} catch(e) {
is_private = true;
}
if (typeof is_private === 'undefined') {
retry(
function isDone() {
return db.readyState === 'done' ? true : false;
},
function next(is_timeout) {
if (!is_timeout) {
is_private = db.result ? false : true;
}
}
);
}
} else if (isIE10OrLater(window.navigator.userAgent)) {
is_private = false;
try {
if (!window.indexedDB) {
is_private = true;
}
} catch (e) {
is_private = true;
}
} else if (window.localStorage && /Safari/.test(window.navigator.userAgent)) {
try {
window.localStorage.setItem('test', 1);
} catch(e) {
is_private = true;
}
if (typeof is_private === 'undefined') {
is_private = false;
window.localStorage.removeItem('test');
}
}
retry(
function isDone() {
return typeof is_private !== 'undefined' ? true : false;
},
function next(is_timeout) {
callback(is_private);
}
);
}
Browser makers are actively patching browser bugs that let sites identify private mode. Some bugs remain, but code to detect them is unlikely to be worth writing as the plan is it won't work for long.
The reason why browser makers are fixing these bugs is that sites like news publishers are using the bugs to identify private-mode users and refuse to serve them. The news publishers who want to do this tend to be using "metered paywalls", which let each browser view a certain number of free articles per day (or per week or whatever) and then start charging: since private-mode effectively resets the meter, the publishers don't want you to use private mode. But restricting private mode also restricts people who want to use it for other reasons, e.g. a domestic-abuse victim not wanting to keep history on a browser shared with their abuser, or someone not wanting their current activity to affect what advertisements they see in future, or some other reason. Although news sites that restrict private mode do tend to permit it if you log in, it's rather obvious that logging in lets them track you, so if you're trying to avoid being tracked then logging-in doesn't seem like an acceptable solution, hence browser makers want publishers not to be able to detect private mode.
There is another way of not keeping history: use a browser that lets you selectively clear it afterwards. Chrome for example can clear cookies, cache and history associated with specific domains, or for a specified period of time such as "for the last hour". That way you don't need private or incognito mode: you can get the same effect by browsing in normal mode and then erasing the traces. But you have to know how to do it, plus you must remember to do it, so it's a more troublesome approach than is using private mode. Still, I expect some people are using this as a workaround if their browser still has a bug that lets sites detect when they're in private mode and deny them service.
If you as a website author have a reason for not wanting your website to be stored in cache or history, for example if the site is meant to help domestic-abuse victims, then "how to detect private mode" might be the wrong question, as what you really want is "don't store this stuff in history, whether private mode is in use or not". Chris Coyier on css-tricks.com noted that window.location.replace() does not create a history item and techniques like this could be used to construct a site that at least doesn't leave its individual pages in history (at least not when browsed with Javascript switched on), but the referring page—possibly a dangerous-to-have search-result page—would still be in history, as would the final page they were on if they don't properly "sign out" of the site. (Intermediate pages might also be discernible via cache forensics, but anyone who can do that can probably also record the traffic as it happens, so we just have to hope the abuser is not that clever.) Another possible approach might be to create an innocent-looking cookie that stores the timestamp of the page's first load, and replace its content with something else if the current time exceeds that timestamp by too long, although its URL may still be loadable on another device or by clearing cookies (unless it was also session-dependent). But getting rid of the referring page is still going to be an issue, and as it's not always possible to confirm the user is in private mode, the best policy is probably to take steps to educate them about private mode anyway.
If you check their User-Agent, you can show them what both private mode and non private mode look like on their browser and OS, ask them to confirm which of the two matches their current window right now, and caution them if they choose the non private mode appearance. This won't work for browser and OS combinations you didn't test (but then neither will bug-based detection), and it assumes the user cares about their security enough to take the question seriously—but if they don't, the battle is probably already lost anyway.
Well, you wouldn't really distinguish private mode from "block all cookies" in that way, but apart from that rare situation I guess it should work.
The big problem IMO, is that this is a very very bad site design, not better than the good ol' "you need browser xxx to see this website" that was common in the '90s. Not all browser have a Private Browsing mode (as much as I despise IE, your cutting out IE7 users for instance) and those users won't be able to access your site at all.
Also, when I'm on the Internet I often have several tabs open with multiple website. It would be really annoying for me to have to switch to private mode just to see that website and not being able to access the other sites at the same time.
One thing you could do would be designing the site using sessions instead of cookies, so they won't be stored (as you don't use them...). And as for the history... really, what's the problem with that?
I've solved this issue by using two HTML pages. The main page define a status variable and set a cookie. The second page is opened in a new window (not tab), read the cookie and set status to the cookie value. Under MSIE, the cookie value is passed to the child page when the main page in normal mode. When in InPrivate Browsing mode, the cookie value is not passed to the child page (but is passed if you open a new tab).
The main.html page:
<script>
var myCookie="nocookie";
document.cookie="checkInPrivate=1";
var h=window.open("child.html", "_blank", "left=9999,height=200,width=200");
setTimeout(function() {
var status=null;
if (myCookie=="nocookie") {
status="unable to determine if we are InPrivate Browsing mode (child page did not set the cookie)";
} else if (myCookie.indexOf("checkInPrivate")>=0) {
status="not in InPrivate Browsing mode (child page did set the cookie)";
} else {
status="in InPrivate Browsing mode (child page set the cookie value but it was not provided)";
}
alert(status);
}, 200);
</script>
The child.html page:
Detecting MSIE's InPrivate Browsing mode...
<script>
window.opener.myCookie=document.cookie;
window.close();
</script>
I'm using InPrivate Browsing mode in order to prevent Browser Helper Objects (BHO) and browser extensions to be enabled, since BHO are most often malwares which can modify the web pages even if HTTPS and strong authentication are used. Internet Explorer 9 has a "Disable toolbars and extensions when InPrivate Browsing starts" in its "Privacy" settings.
However, this is not the ultimate way to prevent malicious browser extension: a malicious extension may change the main page behavior to make it think that the myCookie value has not been set and. We would wrongly assume that we are in InPrivate Browsing mode.
Note that I need cookies for my application so I do not use InPrivate Browsing for that purpose.
Write code to achieve following
1) In firefox test browser version. This method works with version >= 33.0 ( supports service workers ). Cannot use this method with old ( < 33.0 ) versions.
2) Try to set service worker.
3) If you can set,use or access a service worker you are 1000% not in private browsing mode as service workers cannot be interacted with on Firefox private browsing mode. I wish that they could be.
Quote:
"In Firefox, Service Worker APIs are hidden and cannot be used when the user is in private browsing mode"
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers
Not sure if its cause this question is old but Firefox does provide documentation on how to detect private browsing mode. However it involves using an import of theirs DXR PrivateBrowsingUtils:
try {
// Firefox 20+
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
...
}
} catch(e) {
// pre Firefox 20 (if you do not have access to a doc.
// might use doc.hasAttribute("privatebrowsingmode") then instead)
try {
var inPrivateBrowsing = Components.classes["#mozilla.org/privatebrowsing;1"].
getService(Components.interfaces.nsIPrivateBrowsingService).
privateBrowsingEnabled;
if (!inPrivateBrowsing) {
...
}
} catch(e) {
Components.utils.reportError(e);
return;
}
}
While creating my Safari extension, I found out that it was possible to query the boolean safari.self.browserWindow.activeTab.private. Below worked for me to check whether the browser was open in Private or not but only from the extension.
isPrivate = false;
try {
isPrivate = safari.self.browserWindow.activeTab.private;
} catch (_) {
isPrivate = true;
}
if (isPrivate === true){
console.log("Private window.");}
else {
console.log("Not private window.");}
Source: developer.apple.com | Instance Property private
function isPrivate(callback) {
callback || (callback = function(){});
var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
if(fs){
return fs(window.TEMPORARY, 1, callback.bind(this, false), callback.bind(this, true));
}
if(window.indexedDB && /Firefox/.test(window.navigator.userAgent)){
try {
var db = window.indexedDB.open('test');
var tryes = 0;
var interval = limit = 10;
var wait = function(check){
if(tryes >= limit){ return callback(true); } // Give up
return window.setTimeout(check, ++tryes * interval);
}
var evaluate = function(){
return db.readyState === 'done' ? callback(!db.result) : wait(evaluate);
}
return wait(evaluate);
} catch (e) {
return callback(true);
}
}
if (!!window.navigator.userAgent.match(/(MSIE|Trident|Edge)/)){
try {
return callback(!window.indexedDB);
} catch (e) {
return callback(true);
}
}
try {
window.openDatabase(null, null, null, null);
return callback(false);
} catch (e) {
return callback(true);
}
}
isPrivate( function(isPrivate) {
console.log('Private mode ===>', isPrivate);
});
You can find this gist to detect private browsing
var hasStorage = function() {
var mod,
result;
try {
mod = new Date;
localStorage.setItem(mod, mod.toString());
result = localStorage.getItem(mod) === mod.toString();
localStorage.removeItem(mod);
return result;
} catch (_error) {
return false;
}
},
hasCookies = function() {
var cookieEnabled = navigator.cookieEnabled ? true : false;
if (typeof navigator.cookieEnabled == 'undefined' && !cookieEnabled) {
document.cookie = 'testcookie';
cookieEnabled = (document.cookie.indexOf('testcookie') != -1) ? true : false;
}
return cookieEnabled;
};
if (!hasStorage()) {
document.getElementById('apple_storage').style.display = 'block';
} else if (!hasCookies()) {
document.getElementById('no_cookie').style.display = 'block';
}
<!-- ERROR FOR BLOCKED LOCAL STORAGE -->
<div id="apple_storage" style="display:none;">
<div class="modal-new alerts">
<h2>Attenion</h2>
Close
<div class="body">
<p>
Dear customer, to ensure proper use of the site it is necessary to abandon the
private browsing.
</p>
</div><!-- /.body -->
</div>
</div>
<!-- ERROR FOR BLOCKED COOKIES -->
<div id="no_cookie" style="display:none;">
<div class="modal-new alerts">
<h2>Attenion</h2>
Close
<div class="body">
<p>
Dear customer, to ensure proper use of the site it is necessary to enable cookies.
</p>
</div><!-- /.body -->
</div>
</div>

Access specific cookies by domain/name in Firefox extension

I am developing a Firefox extension and need to access a specific cookie from a specific domain. I have this code which fetches all cookies for all domains, how do I request only the cookie that I am looking for.
var {Cc, Ci} = require("chrome");
var cookieManager = Cc["#mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
var count = cookieManager.enumerator;
while (count.hasMoreElements()){
var cookie = count.getNext();
if (cookie instanceof Ci.nsICookie){
console.log(cookie.host);
console.log(cookie.name);
console.log(cookie.value);
}
}
To sum up, I am able to find the cookie that I am looking for with the code above but I don't want to have to iterate through all of the cookies from all domains.
You can use nsICookieManager2 interface (the original nsICookieManager interface was frozen and couldn't be changed which is why this extended version was created):
var cookieManager = Cc["#mozilla.org/cookiemanager;1"]
.getService(Ci.nsICookieManager2);
var count = cookieManager.getCookiesFromHost("example.com");
Note: the concept of frozen interfaces was dropped in Gecko 2.0 (Firefox 4). Since then some interfaces similar to nsICookieManager/nsICookieManager2 have been unified - so in a future Firefox version nsICookieManager2 might go away as well, all the functionality will be exposed on nsICookieManager then.

Categories

Resources