2

https://jsfiddle.net/n0hnu5te/1/ this script is a browser incognito mode detector and it's working well on JsFiddle but it is not working on my hosting and localhost. I tried some ways like onload etc. but nothing changed.

Could you explain what is the problem, please?

My Code is:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>Title</title>
</head>
<body>
<script>
// Detect private browsing
// Inpired by original gist: https://gist.github.com/cou929/7973956
// But based in general on comment: https://gist.github.com/cou929/7973956#gistcomment-1791792 and other comments
(function (window) {
    var on, off;

    function Webkit() {
        if (window.webkitRequestFileSystem) {
            window.webkitRequestFileSystem(window.TEMPORARY, 1, off, on);
            return true;
        }
    }

    function Mozilla() {
        if ('MozAppearance' in document.documentElement.style) {
            const db = indexedDB.open('test');
            db.onerror = on;
            db.onsuccess = off;
            return true;
        }
    }

    function Safari() {
        if (/constructor/i.test(window.HTMLElement)) {
            // iOS 11
            // Origin: https://gist.github.com/cou929/7973956#gistcomment-2272103
            try {
                window.openDatabase(null, null, null, null);
            } catch (e) {
                on();
            }

            // Older Safari
            try {
                if (localStorage.length)
                    off();
                else {
                    localStorage.x = 1;
                    localStorage.removeItem('x');
                    off();
                }
            } catch (e) {
                // Original gist: https://gist.github.com/jherax/a81c8c132d09cc354a0e2cb911841ff1

                // 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();
            }

            return true;
        }
    }

    function IE10Edge() {
        if (!window.indexedDB && (window.PointerEvent || window.MSPointerEvent)) {
            on();
            return true;
        }
    }

    window.isPrivate = function (on_cb, off_cb) {
        on = on_cb || function () {};
        off = off_cb || function () {};
        Webkit() || Mozilla() || Safari() || IE10Edge() || off();
    };
})(window);

isPrivate(
    function () {document.body.innerHTML = 'Private browsing: <b>ON</b>'},
    function () {document.body.innerHTML = 'Private browsing: <b>OFF</b>'}
);


</script>
</body>
</html>

Stackoverflow wants more details but I think I wrote all details. So these paragraph is not important.

Barmar
  • 741,623
  • 53
  • 500
  • 612
Topup
  • 41
  • 3
  • In what way is it not working? Is it reporting ON when it should be OFF, or OFF when it should be ON? – Barmar Oct 07 '21 at 15:54
  • It reports a false positive in the stack snippet, probably because of the way it's sandboxed. – Barmar Oct 07 '21 at 15:54
  • It's always show OFF. Can not detect incognito mode on localhost or any other host. @Barmar – Topup Oct 07 '21 at 16:17
  • Are there any errors in the JavaScript console? – Barmar Oct 07 '21 at 16:18
  • No, there is no error on console. @Barmar – Topup Oct 07 '21 at 16:26
  • And this happens in all different browsers? – Barmar Oct 07 '21 at 16:29
  • It's working on Firefox but not working on chromium based browsers. ( JsFiddle working on both ) @Barmar – Topup Oct 07 '21 at 16:40
  • Is the `if` statement failing, or is it calling the wrong callback from `webkitRequestFileSystem`? Add `console.log()` statements to see what's happening. – Barmar Oct 07 '21 at 16:56
  • Normally "window.webkitRequestFileSystem" return undefined on incoginito mode when I try on Jsfiddle, but it's return object on incognito mode when I try on my own host or localhost. @Barmar – Topup Oct 07 '21 at 18:53

2 Answers2

1

As someone with a lot of experience in detecting private browsing modes in browsers, here's a few tips.

But for your code in particular:

  • Your Chrome/Webkit method does not work as of Chrome 76.
  • Your Firefox code is over-complicated, just check for whether navigator.serviceWorker is defined or not. It's not defined in private.
  • Apple tries to mitigate private browsing detection frequently, so your Safari code won't work for Safari 13 or higher.
  • MSIE code is functional and will work.

Please note this was written in November 2021. Methods for detecting private browsing modes is an arms race, so this advice may no longer hold up in the future.

Joe Rutkowski
  • 171
  • 1
  • 3
  • 6
0

Original jsfiddle iframe (your script run "ok"):

<iframe name="result" allow="midi; geolocation; microphone; camera; display-capture; encrypted-media;" allowfullscreen="" allowpaymentrequest="" frameborder="0" src="" sandbox="allow-modals allow-forms allow-scripts allow-same-origin allow-popups allow-top-navigation-by-user-activation allow-downloads"></iframe>

With removed sandbox attribute (your script fail):

<iframe name="result" allow="midi; geolocation; microphone; camera; display-capture; encrypted-media;" allowfullscreen="" allowpaymentrequest="" frameborder="0" src=""></iframe>

The problem is in the sandbox attribute that jsfiddle sets in the iframe with which sandbox your script.

You must avoid testing these types of scripts in an online service. You can run your code as a snippet in chrome devtools or as simple html page and see that the problem is just how you detect incognito mode.

Also pay attention to the order in which you check the features for the various browsers and the use or not of proprietary prefixes.

Keep in mind that, like all feature detections, they can change their result when the browser version changes.

This may help you for Chrome https://stackoverflow.com/a/27805491/3679111

Marco Sacchi
  • 712
  • 6
  • 21