Определение, использует ли браузер режим приватного просмотра - PullRequest
57 голосов
/ 19 мая 2010

Я создаю экстранет для компании, параноидальной по поводу безопасности. Они хотят убедиться, что (среди прочего) их пользователи просматривают сайт с включенным режимом приватного просмотра в их веб-браузере, чтобы не сохранять куки или историю.

Я нашел только это http://jeremiahgrossman.blogspot.com/2009/03/detecting-private-browsing-mode.html а также https://serverfault.com/questions/18966/force-safari-to-operate-in-private-mode-and-detect-that-state-from-a-webserver

Идеальное решение - использовать javascript без кода или с минимальным. Будет ли попытка установить уникальный файл cookie для всех браузеров и платформ? Кто-нибудь делал это раньше?

спасибо!


обновление

http://crypto.stanford.edu/~collinj/research/incognito/ использует технику посещения CSS отпечатков пальцев браузера, упомянутых в других постерах - спасибо за подсказки.

Мне это нравится, потому что оно маленькое и элегантное, но, тем не менее, я хочу иметь возможность делать это без JavaScript, если это возможно.

Ответы [ 16 ]

42 голосов
/ 25 марта 2014

Обновление июнь 2019

Google исключает возможность для постоянного обнаружения режима приватного просмотра в Chrome 76 и далее. Итак, если вы хотите обнаружить приватный просмотр, теперь это невозможно (если только вы не найдете способ сделать это, которого Google не нашел). Возможность обнаружения частного режима просмотра была признана ошибкой и никогда не предназначалась.

Для всех, кто сталкивался с этим вопросом, обратите внимание, что с 2014 года не существует надежного или точного способа определить, просматривает ли кто-либо в режиме инкогнито / приват / безопасный просмотр через Javascript или CSS. Предыдущие решения, которые когда-то работали подобно хакерской истории CSS, с тех пор стали недоступными для всех поставщиков браузеров.

Никогда не должно быть ситуации, когда когда-либо требуется обнаружение режима частного просмотра на обычном повседневном веб-сайте. Люди выбирают просмотр анонимно или не анонимно по своим причинам.

Браузеры, такие как Chrome и Firefox, больше не отключают такие функции, как localStorage. Они просто помещают пространство имен во временное местоположение, чтобы предотвратить появление ошибок на сайтах, которые его используют. По завершении просмотра пространство имен стирается и ничего не сохраняется. Если вы тестируете поддержку localStorage независимо от режима, она всегда будет возвращать true для браузеров, которые ее поддерживают.

Другие средства обнаружения частного режима в Chrome, в частности, были полностью исправлены и больше не будут работать.

Если это требуется внутри компании, вам следует разработать плагин для браузера. В частности, Chrome и Firefox предоставляют внутренние API-интерфейсы, которые позволяют плагинам проверять, находится ли пользователь в режиме приватного просмотра / инкогнито, и соответственно действовать. Это не может быть сделано вне плагина.

41 голосов
/ 19 июля 2013

Вот более простой способ определения режима конфиденциальности. Это работает только в Safari. Я создал его, потому что разрабатываемое мной веб-приложение использует localStorage. LocalStorage недоступен в Safari в режиме конфиденциальности, поэтому мое приложение не будет работать. При загрузке страницы запустите скрипт ниже. Он показывает окно предупреждения, если мы не можем использовать 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.');
}
20 голосов
/ 25 декабря 2016

Можно обнаружить включенные частные режимы просмотра для большинства используемых браузеров. Это включает в себя Safari, Firefox, IE10, Edge и Google Chrome.


Firefox

Когда включен режим частного просмотра Firefox, IndexedDB генерирует InvalidStateError, поскольку он недоступен в режиме частного просмотра.

Очень, если что:

var db = indexedDB.open("test");
db.onerror = function(){/*Firefox PB enabled*/};
db.onsuccess =function(){/*Not enabled*/};

Safari

Для Safari ключом является служба локального хранилища. Это отключено в режиме конфиденциальности. Так что попробуйте получить к нему доступ и использовать предложение try-catch. Следующий метод работает на устройствах OSX и iOS. Кредиты для этого метода собираются на этот вопрос и ответ

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 / Край

Internet Explore даже отключит IndexedDB в режиме конфиденциальности. Так что проверь на существование. Но этого недостаточно, потому что старые браузеры, возможно, даже не имеют IDB. Так что сделайте еще одну проверку, например для событий, которые есть только в IE10 и последующих браузерах. Соответствующий вопрос по CodeReview можно найти здесь

if(!window.indexedDB && (window.PointerEvent || window.MSPointerEvent)){
 //Privacy Mode
}

Chrome

Режим инкогнито Chromes может быть проверен файловой системой. Отличное объяснение можно найти здесь на 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
});
16 голосов
/ 07 мая 2016

Вот мой взгляд на обнаружение приватного режима

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 нашел современный, более быстрый и синхронный способ попробовать его в Firefox (у них нет обслуживающего персонала в приватном режиме), похожий на т.е. не включающий indexedDB, но тест работает только в защищенном сайты

: "MozAppearance" in document.documentElement.style ? navigator.serviceWorker ? off() : on()
14 голосов
/ 19 мая 2010

Ваша веб-страница не может абсолютно точно знать, что пользователь находится в режиме приватного просмотра. Любые попытки проверить различные функции браузера должны будут часто меняться по мере обновления реализаций безопасности. Это может работать некоторое время в некоторых браузерах, но не во всех.

Если компания обеспокоена безопасностью, я бы предложил развернуть свой собственный дистрибутив Firefox или Chromium с заблокированными настройками конфиденциальности и разрешить этому клиенту только подключение к экстрасети.

4 голосов
/ 12 июля 2017

Трюк localStorage это ошибка, которая была исправлена ​​, и она больше не работает в Safari 11.0.

Существует интересная альтернатива, которая работает в Safari, Opera и Internet Explorer (не Chrome): эти браузеры отправляют заголовок DNT: 1 (Не отслеживать).

Это не на 100% надежно, поскольку этот заголовок можно включить для обычного просмотра (по умолчанию он отключен), но он может помочь идентифицировать пользователей, которые заботятся о конфиденциальности.

3 голосов
/ 25 октября 2011

Вы не будете блокировать их, если у них не включен частный просмотр.

Зачем вообще иметь умное окно сообщения?

Будет ли попытка установить уникальный файл cookie для всех браузеров и платформ? Кто-нибудь делал это раньше?

Я думаю, что самым элегантным решением было бы:

  • Выполнить проверку на утечку безопасности
  • Если проверка на утечку обнаружит проблему
    • Скажите пользователю проверить настройки
    • Предложить режим конфиденциальности

Потому что, как вы сказали, не каждый может или должен включить режим конфиденциальности.

2 голосов
/ 19 марта 2019

Я создал небольшую библиотеку, которая будет работать на всех основных протестированных платформах и браузерах: https://github.com/jLynx/PrivateWindowCheck

Вы можете просто позвонить

isPrivateWindow(function(is_private) {
    if(is_private)
        alert('Private');
    else
        alert('Not Private');
});
2 голосов
/ 27 апреля 2016

Я согласен с мнением DigitalSeas о том, что мы, как правило, не должны пытаться определить, находится ли пользователь в режиме «частного просмотра». Однако недавно я обнаружил, что FireFox теперь подписывается на службу под названием «connect.me», которая предоставляет черный список URL-адресов, который они используют в своей функции «отслеживания защиты» . Поскольку disconnect.me помещает в черный список некоторые социальные сети (например, facebook.net ) Facebook, мы обнаружили, что их SDK не будут загружаться в FireFox. Поэтому кажется разумным, что мы могли бы попытаться определить режим частного просмотра, чтобы предоставить более полезное и точное сообщение об ошибке нашим пользователям.

С учетом этого оправдания, эта сущность утверждает, что обеспечивает обнаружение частного просмотра в основных браузерах, используя приемы, специфичные для этих браузеров. На момент написания этой статьи (возможно, суть была обновлена ​​к тому времени, когда вы ее прочитали), логика обнаружения выглядит следующим образом:

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);
        }
    );
}
2 голосов
/ 19 мая 2010

Веб-браузеры ведут себя по-разному , когда включен режим конфиденциальности.

Во многих браузерах кеширование ресурсов ограничено. Можно определить , где браузер был , основываясь на их CSS-кэше. Эту атаку можно провести без JavaScript .

EFF работает над проектом для браузеров отпечатков пальцев . Части отпечатков браузеров будут отличаться при включении режима конфиденциальности. Давай, попробуй .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...