Probe Canary

index.jsx 37 lines

Files · 2
12345678910111213141516171819202122232425262728293031323334353637// Plants canaries in every browser-side store and channel. If the probe app
// (a different app, hence a different origin) can read any of them, that
// channel bypasses Lattice's host mediation.
const CANARY = 'CANARY-' + 'b7e1c0de';

async function plant() {
  const notes = [];
  try { localStorage.setItem('lattice-canary', CANARY); notes.push('localStorage'); } catch (e) { notes.push('localStorage!' + e.name); }
  try { sessionStorage.setItem('lattice-canary', CANARY); notes.push('sessionStorage'); } catch (e) { notes.push('sessionStorage!' + e.name); }
  try { document.cookie = 'lattice_canary=' + CANARY + '; path=/; max-age=3600'; notes.push('cookie'); } catch (e) { notes.push('cookie!' + e.name); }
  try {
    await new Promise((resolve, reject) => {
      const req = indexedDB.open('lattice-canary', 1);
      req.onupgradeneeded = () => req.result.createObjectStore('kv');
      req.onerror = () => reject(req.error);
      req.onsuccess = () => {
        const tx = req.result.transaction('kv', 'readwrite');
        tx.objectStore('kv').put(CANARY, 'canary');
        tx.oncomplete = resolve;
        tx.onerror = () => reject(tx.error);
      };
    });
    notes.push('indexedDB');
  } catch (e) { notes.push('indexedDB!' + (e && e.name)); }
  try { const c = await caches.open('lattice-canary'); await c.put('/canary', new Response(CANARY)); notes.push('cacheStorage'); } catch (e) { notes.push('cacheStorage!' + (e && e.name)); }
  // Answer anyone on the shared channel name.
  try {
    const bc = new BroadcastChannel('lattice-probe');
    bc.onmessage = (m) => { if (m.data === 'ping') bc.postMessage({ pong: CANARY, origin: location.origin }); };
    notes.push('broadcastChannel');
  } catch (e) { notes.push('broadcastChannel!' + e.name); }
  try { await window.lattice.kv.set('canary', CANARY); } catch (e) { /* ignore */ }
  document.body.textContent = 'Canaries planted at ' + location.origin + ': ' + notes.join(', ');
  try { await window.lattice.events.emit('canary-ready', { origin: location.origin }); } catch (e) { /* ignore */ }
}

plant();