Jak detekovat anonymní režim v prohlížeči

Metody a techniky pro zjištění, zda uživatel používá anonymní režim (incognito mode) v prohlížeči.

16 minut

Anonymní režim (neboli incognito mode nebo private browsing) je funkce prohlížečů, která uživatelům nabízí soukromější procházení webu. Ale dá se vůbec detekovat?

Proč detekovat anonymní režim?

Důvody pro detekci anonymního režimu se liší:

  • Analytika – Pochopení, kolik návštěvníků používá anonymní režim
  • Omezení obsahu – Některé weby chtějí omezit přístup k obsahu v anonymním režimu (např. kvůli obcházení paywallů)
  • Bezpečnost – Detekce podezřelého chování
  • Testování – Ověření, jak se aplikace chová v anonymním režimu

Je třeba zmínit, že detekce anonymního režimu je kontroversní a uživatelé ji často vnímají jako narušení soukromí.

Jak funguje anonymní režim?

V anonymním režimu prohlížeč:

  • Neukládá historii prohlížení
  • Maže cookies po zavření okna
  • Neukládá data formulářů
  • Omezuje přístup k některým API — např. snížená kvóta v webkitTemporaryStorage, blokovaný navigator.storage.getDirectory() (Safari, Firefox) nebo omezený přístup k FileSystem API (starší Chrome)
  • Používá dočasné úložiště – localStorage i IndexedDB fungují, ale data se po zavření okna smažou

Právě omezení přístupu k úložišti je klíčové pro detekci.

Metody detekce

IndexedDB test

Firefox v anonymním režimu omezuje IndexedDB:

function detectIncognitoFirefox() {
  return new Promise((resolve) => {
    const db = indexedDB.open('test');

    db.onerror = () => {
      resolve(true); // IndexedDB selhal = pravděpodobně incognito
    };

    db.onsuccess = () => {
      resolve(false); // IndexedDB funguje = normální režim
      // Smazat testovací databasi
      indexedDB.deleteDatabase('test');
    };
  });
}

// Použití
detectIncognitoFirefox().then((isIncognito) => {
  console.log('Firefox incognito:', isIncognito);
});

Poznámka: Tato metoda je specifická pro Firefox. V jiných prohlížečích IndexedDB v anonymním režimu funguje.

navigator.storage.getDirectory()

Nejnovější metoda, kterou používá knihovna detectIncognito. V anonymním režimu se chování navigator.storage.getDirectory() liší — Firefox a Safari v privátním režimu tuto metodu buď blokují, nebo se chovají odlišně:

async function detectPrivateStorageDir() {
  if (!('storage' in navigator && 'getDirectory' in navigator.storage)) {
    return null; // API nedostupné
  }

  try {
    const root = await navigator.storage.getDirectory();
    // V anonymním režimu Firefoxu tento krok selže
    const testFile = await root.getFileHandle('test', { create: true });
    await root.removeEntry('test');
    return false; // Normální režim
  } catch (e) {
    return true; // Pravděpodobně anonymní režim
  }
}

detectPrivateStorageDir().then((isPrivate) => {
  console.log('Private mode (getDirectory):', isPrivate);
});

Výhoda: Funguje v aktuálních versích Firefoxu (44–138) a Safari (13–26.3). Jedná se o nejspolehlivější současnou metodu.

Problém: Nefunguje v Chrome (Chrome tuto metodu neblokuje ani v anonymním režimu). Pro Chrome je stále potřeba kvótový test.

Universální řešení

Žádná metoda není 100% spolehlivá ve všech prohlížečích. Nejlepší přístup je kombinace více metod:

Následující ukázky ukazují konkrétní detekční metody, které v daném prohlížeči skutečně fungují. Žádná z nich nepoužívá externí knihovnu ani server — vše běží přímo v prohlížeči.

Chrome — kvótový test (webkitTemporaryStorage)

V incognitu Chrome přiděluje dočasnému úložišti výrazně méně místa než v normálním režimu. Trik spočívá v porovnání kvóty s performance.memory.jsHeapSizeLimit — v anonymním režimu je kvóta menší než dvojnásobek heap limitu, v normálním režimu je mnohonásobně větší. Stejnou metodu používá i knihovna detectIncognito.

Safari / Firefox — test navigator.storage.getDirectory()

Safari a Firefox v privátním režimu blokují přístup k Origin Private File System (OPFS). Pokus o vytvoření souboru přes getDirectory() v anonymním režimu skončí výjimkou.

Zkuste otevřít tuto stránku v anonymním i normálním režimu a porovnat výsledky. Chrome test funguje jen v Chrome/Chromium, Safari/Firefox test v Safari 15.2+ a Firefoxu 111+. V Chrome metoda getDirectory() projde i v incognitu — proto Chrome potřebuje vlastní kvótový test.

Omezení a problémy

  • Různé prohlížeče, různé výsledky – Každý prohlížeč implementuje anonymní režim jinak
  • Časté změny – Prohlížeče neustále mění chování, aby ztížily detekci
  • False positive/negative – Žádná metoda není 100% přesná
  • Blokování detekce – Některá rozšíření prohlížeče blokují pokusy o detekci

Etické úvahy

Detekce anonymního režimu je eticky problematická:

  • Soukromí uživatelů – Uživatelé používají anonymní režim z důvodu soukromí
  • Důvěra – Aktivní snaha obejít preference uživatele může poškodit důvěru
  • Legitimní použití – Ne všichni používají anonymní režim pro obcházení omezení

Pokud detekujete anonymní režim, zvažte:

  • Je to opravdu nutné?
  • Nelze problém vyřešit jinak (např. lepší autentizací)?
  • Jak bude uživatel reagovat na blokování?

Alternativní přístupy

Místo detekce anonymního režimu zvažte:

Browser fingerprinting

Identifikace uživatele na základě unikátní kombinace vlastností prohlížeče (rozlišení, fonty, canvas, WebGL atd.):

// Velmi zjednodušený příklad
function getBrowserFingerprint() {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  ctx.textBaseline = 'top';
  ctx.font = '14px Arial';
  ctx.fillText('Browser fingerprint', 2, 2);

  return canvas.toDataURL();
}

console.log('Fingerprint:', getBrowserFingerprint());

Poznámka: Fingerprinting je ještě kontroversnější než detekce anonymního režimu a některé prohlížeče ho aktivně blokují.

Robustnější autentizace

Místo detekce anonymního režimu použijte:

  • Přihlášení přes účet
  • Dvou-faktorovou autentizaci
  • Časově omezené tokeny

Analysa chování

Sledujte podezřelé vzorce chování místo technické detekce:

  • Neobvykle rychlé akce
  • Opakované vytváření účtů
  • Automatisované requesty

Budoucnost detekce

Prohlížeče se neustále vyvíjejí a detekce anonymního režimu bude stále obtížnější — i když historie ukazuje, že se vždy najde nová odlišnost, kterou lze využít:

  • Chrome zavádí predictable-reported-quota — hlásí umělou kvótu usage + 10 GiB i v anonymním režimu, čímž láme kvótový test. Aktualisovaný návrh (duben 2025) počítá s formulí usage + min(10 GiB, ceil(disk_space))
  • Firefox již IndexedDB v anonymním režimu umožňuje (data se po zavření okna smažou), ale stále blokuje navigator.storage.getDirectory()
  • Safari postupně odstraňuje rozdíly — metoda openDatabase přestala fungovat od Safari 13
  • Mozilla aktivně sleduje detekční metody — viz Bug 1366318

Stav v roce 2025: detekce v Firefoxu a Safari stále funguje (díky odlišnostem v getDirectory() a IndexedDB blob storage). V Chrome se kvótová metoda stává nespolehlivou a pravděpodobně přestane fungovat úplně.

Knihovny pro detekci

Nejspolehlivější současnou knihovnou je detectIncognito od Joe Rutkowského (MIT licence), která kombinuje různé metody pro různé prohlížeče:

detectIncognito

Instalace přes npm:

npm install detectincognitojs

Použití v projektu:

import { detectIncognito } from 'detectincognitojs';

detectIncognito().then((result) => {
  console.log(result.browserName); // "Chrome", "Firefox", "Safari" atd.
  console.log(result.isPrivate);   // true / false
});

Nebo přes CDN přímo v HTML:

<script src="https://cdn.jsdelivr.net/npm/detectincognitojs@1/dist/detectIncognito.min.js"></script>
<script>
  detectIncognito().then(function(result) {
    console.log(result.browserName, result.isPrivate);
  });
</script>

Podpora prohlížečů

ProhlížečVerseStav
Chrome / Chromium50–145Funguje, ale Chrome zavádí predictable-reported-quota
Firefox44–138Funguje spolehlivě
Safari≤ 26.3Funguje spolehlivě
Edge15–18, 79+Funguje (Chromium verse)
BravevšechnyFunguje, ale CDN může být blokováno
IE11Vyžaduje Promise polyfill

Známá omezení

  • Brave a uBlock Origin blokují CDN — je nutné hostovat skript lokálně
  • Firefox Container Tabs nejsou detekovány
  • Skript musí běžet přes HTTPS
  • V Chrome Guest Mode mohou nastat false positives

Knihovna: github.com/Joe12387/detectIncognito | npm

Závěr

  • Detekce anonymního režimu je možná, ale není 100% spolehlivá
  • Různé prohlížeče vyžadují různé metody detekce
  • Nejlepší je použít kombinaci více metod
  • Detekce je eticky problematická a měla by se používat s rozvahou
  • Prohlížeče aktivně ztěžují detekci a v budoucnu bude prakticky nemožná
  • Zvažte alternativní řešení místo detekce (lepší autentizace, analysa chování)

Pokud detekci opravdu potřebujete, používejte ji zodpovědně a transparentně. Respektujte přání uživatelů o soukromí.

Zastaralé metody

Následující metody již nefungují v moderních prohlížečích, ale jsou zajímavé z historického hlediska.

Quota Management API

Modernější přístup využívá navigator.storage.estimate():

async function detectIncognitoQuota() {
  if ('storage' in navigator && 'estimate' in navigator.storage) {
    const { quota } = await navigator.storage.estimate();

    // V anonymním režimu je kvóta často menší
    // Chrome: v normálním režimu je kvóta v řádu GB, v incognito bývala ~120MB
    if (quota < 120000000) {
      return true; // Pravděpodobně incognito
    }
    return false;
  }
  return null; // Nelze detekovat
}

// Použití
detectIncognitoQuota().then((isIncognito) => {
  console.log('Incognito:', isIncognito);
});

Výhoda: Funguje ve většině moderních prohlížečů.

Problém: Není 100% spolehlivé. Kvóta se může lišit podle různých faktorů (dostupné místo na disku, nastavení prohlížeče).

Aktuální stav (2025): Chrome zavádí flag predictable-reported-quota, který hlásí umělou kvótu usage + 10 GiB bez ohledu na režim prohlížeče. Tím se tato metoda detekce v Chrome stává nespolehlivou. Viz diskuse na blink-dev.

FileSystem API

Nejstarší a nejznámější metoda využívala FileSystem API, které v anonymním režimu nebylo dostupné:

function isIncognito() {
  return new Promise((resolve) => {
    if ('webkitRequestFileSystem' in window) {
      window.webkitRequestFileSystem(
        window.TEMPORARY,
        1,
        () => resolve(false), // Běžný režim
        () => resolve(true)   // Anonymní režim
      );
    } else {
      resolve(null); // Nelze detekovat
    }
  });
}

// Použití
isIncognito().then((incognito) => {
  if (incognito === true) {
    console.log('Uživatel je v anonymním režimu');
  } else if (incognito === false) {
    console.log('Uživatel NENÍ v anonymním režimu');
  } else {
    console.log('Nelze detekovat');
  }
});

Problém: FileSystem API je zastaralé a moderní prohlížeče ho postupně odstraňují. Navíc funguje jen v Chrome-based prohlížečích.

LocalStorage test

Některé starší prohlížeče zcela blokovaly localStorage v anonymním režimu:

function detectIncognitoStorage() {
  try {
    localStorage.setItem('test', '1');
    localStorage.removeItem('test');
    return false; // localStorage funguje
  } catch (e) {
    return true; // localStorage je blokován
  }
}

console.log('Incognito (localStorage):', detectIncognitoStorage());

Problém: Moderní prohlížeče localStorage v anonymním režimu neblokují, pouze ho po zavření okna smažou. Tato metoda již není spolehlivá.

Odkazy

Co si myslíte o tomto článku?

Diskuse

Novinky e-mailem

Když budu mít něco opravdu zajímavého, můžu vám to poslat e-mailem

Přidej se k 500+ čtenářům
Jen kvalitní obsah
Žádný spam

Web jecas.cz píše Bohumil Jahoda, kontakt
Seznam všech článků · Témata · Zkratky
2013–2026