;(function() { window.createMeasureObserver = (measureName) => { var markPrefix = `_uol-measure-${measureName}-${new Date().getTime()}`; performance.mark(`${markPrefix}-start`); return { end: function() { performance.mark(`${markPrefix}-end`); performance.measure(`uol-measure-${measureName}`, `${markPrefix}-start`, `${markPrefix}-end`); performance.clearMarks(`${markPrefix}-start`); performance.clearMarks(`${markPrefix}-end`); } } }; /** * Gerenciador de eventos */ window.gevent = { stack: [], RUN_ONCE: true, on: function(name, callback, once) { this.stack.push([name, callback, !!once]); }, emit: function(name, args) { for (var i = this.stack.length, item; i--;) { item = this.stack[i]; if (item[0] === name) { item[1](args); if (item[2]) { this.stack.splice(i, 1); } } } } }; var runningSearch = false; var hadAnEvent = true; var elementsToWatch = window.elementsToWatch = new Map(); var innerHeight = window.innerHeight; // timestamp da última rodada do requestAnimationFrame // É usado para limitar a procura por elementos visíveis. var lastAnimationTS = 0; // verifica se elemento está no viewport do usuário var isElementInViewport = function(el) { var rect = el.getBoundingClientRect(); var clientHeight = window.innerHeight || document.documentElement.clientHeight; // renderizando antes, evitando troca de conteúdo visível no chartbeat-related-content if(el.className.includes('related-content-front')) return true; // garante que usa ao mínimo 280px de margem para fazer o lazyload var margin = clientHeight + Math.max(280, clientHeight * 0.2); // se a base do componente está acima da altura da tela do usuário, está oculto if(rect.bottom < 0 && rect.bottom > margin * -1) { return false; } // se o topo do elemento está abaixo da altura da tela do usuário, está oculto if(rect.top > margin) { return false; } // se a posição do topo é negativa, verifica se a altura dele ainda // compensa o que já foi scrollado if(rect.top < 0 && rect.height + rect.top < 0) { return false; } return true; }; var asynxNextFreeTime = () => { return new Promise((resolve) => { if(window.requestIdleCallback) { window.requestIdleCallback(resolve, { timeout: 5000, }); } else { window.requestAnimationFrame(resolve); } }); }; var asyncValidateIfElIsInViewPort = function(promise, el) { return promise.then(() => { if(el) { if(isElementInViewport(el) == true) { const cb = elementsToWatch.get(el); // remove da lista para não ser disparado novamente elementsToWatch.delete(el); cb(); } } }).then(asynxNextFreeTime); }; // inicia o fluxo de procura de elementos procurados var look = function() { if(window.requestIdleCallback) { window.requestIdleCallback(findByVisibleElements, { timeout: 5000, }); } else { window.requestAnimationFrame(findByVisibleElements); } }; var findByVisibleElements = function(ts) { var elapsedSinceLast = ts - lastAnimationTS; // se não teve nenhum evento que possa alterar a página if(hadAnEvent == false) { return look(); } if(elementsToWatch.size == 0) { return look(); } if(runningSearch == true) { return look(); } // procura por elementos visíveis apenas 5x/seg if(elapsedSinceLast < 1000/5) { return look(); } // atualiza o último ts lastAnimationTS = ts; // reseta status de scroll para não entrar novamente aqui hadAnEvent = false; // indica que está rodando a procura por elementos no viewport runningSearch = true; const done = Array.from(elementsToWatch.keys()).reduce(asyncValidateIfElIsInViewPort, Promise.resolve()); // obtém todos os elementos que podem ter view contabilizados //elementsToWatch.forEach(function(cb, el) { // if(isElementInViewport(el) == true) { // // remove da lista para não ser disparado novamente // elementsToWatch.delete(el); // cb(el); // } //}); done.then(function() { runningSearch = false; }); // reinicia o fluxo de procura look(); }; /** * Quando o elemento `el` entrar no viewport (-20%), cb será disparado. */ window.lazyload = function(el, cb) { if(el.nodeType != Node.ELEMENT_NODE) { throw new Error("element parameter should be a Element Node"); } if(typeof cb !== 'function') { throw new Error("callback parameter should be a Function"); } elementsToWatch.set(el, cb); } var setEvent = function() { hadAnEvent = true; }; window.addEventListener('scroll', setEvent, { capture: true, ive: true }); window.addEventListener('click', setEvent, { ive: true }); window.addEventListener('resize', setEvent, { ive: true }); window.addEventListener('load', setEvent, { once: true, ive: true }); window.addEventListener('DOMContentLoaded', setEvent, { once: true, ive: true }); window.gevent.on('allJSLoadedAndCreated', setEvent, window.gevent.RUN_ONCE); // inicia a validação look(); })();
  • AssineUOL
Topo

Facebook ainda espia o que você faz no iPhone; veja como impedir

Instagram e Facebook injetam código de rastreamento na navegação in-app, burlando política de transparência da Apple - Getty Images
Instagram e Facebook injetam código de rastreamento na navegação in-app, burlando política de transparência da Apple Imagem: Getty Images

Nicole D'Almeida

Colaboração para Tilt

12/08/2022 14h54Atualizada em 12/08/2022 16h06

O Instagram e o Facebook estão usando seu navegador embutido para rastrear o que os usuários de iOS (iPhone e iPad) fazem em sites externos — desde dados de formulários, como senhas e cartões de crédito, até cada toque. Felix Krause, ex-engenheiro do Google e pesquisador de privacidade, detalhou em seu blog.

Os dois aplicativos têm se aproveitado o fato de que os links nestas redes sociais são direcionados automaticamente para páginas da web em um "navegador in-app", controlado pelo próprio Facebook ou Instagram, em vez de serem abertos no navegador do celular (Chrome, Safari ou outro de sua preferência).

Desta forma, a Meta — empresa-mãe do Facebook e do Instagram — também consegue monitore tudo o que fazemos em sites externos, sem o consentimento do usuário nem do provedor do site.

"O aplicativo Instagram injeta seu código de rastreamento em todos os sites exibidos, inclusive ao clicar em anúncios, permitindo que eles monitorem todas as interações do usuário, como todos os botões e links tocados, seleções de texto, capturas de tela, bem como quaisquer entradas de formulário, como senhas, endereços e números de cartão de crédito", diz Krause.

Vale ressaltar que, segundo pesquisador, nenhum código deste tipo foi adicionado ao navegador do WhatsApp.

Como burlar a transparência?

A Apple trabalha contra o rastreamento entre hosts desde o iOS 14.5, com o recurso de transparência App Tracking Transparency, que obriga os apps a solicitarem a permissão do usuário antes de rastrearem seus dados em aplicativos terceiros, de outras empresas.

No entanto, parece que a Meta encontrou uma brecha para contornar essa regra, usando um código JavaScript personalizado nos navegadores dos apps. Segundo Krause, o arquivo externo que os aplicativos do Instagram e do Facebook injetam é o connect.facebook.net/en_US/pcm.js, que constrói uma ponte para se comunicar com o aplicativo host.

"O aplicativo Instagram injeta seu código de rastreamento em todos os sites exibidos, inclusive ao clicar em anúncios, permitindo que eles monitorem todas as interações do usuário, como todos os botões e links tocados, seleções de texto, capturas de tela, bem como quaisquer entradas de formulário, como senhas, endereços e números de cartão de crédito", disse Krause.

Em um comunicado, a Meta justificou que esta injeção de código de rastreamento ajuda a agregar eventos — leia-se compras online — antes que sejam usados para publicidade direcionada e medição para a plataforma do Facebook.

"Desenvolvemos intencionalmente este código [Peça para rastrear] para honrar as escolhas das pessoas em nossas plataformas", declarou um porta-voz ao The Guardian. "O código nos permite agregar dados do usuário antes de usá-los para publicidade direcionada ou fins de medição. Não adicionamos pixels. O código é injetado para que possamos agregar eventos de conversão de pixels."

Como se proteger

Sempre que você tocar em um link no Instagram ou no Facebook, opte por abri-lo no navegador Safari, nativo dos iPhones e iPads. Ele, por padrão, já bloqueia cookies de terceiros por padrão.

Ainda não há uma maneira de fazer isso automaticamente, é preciso redirecionar manualmente:

$escape.getH()uolbr_geraModulos('animated-gif','/2022/trocar-o-navegador-1660331033794.vm')

  1. e o link diretamente na rede social;
  2. Toque nos três pontinhos no canto superior direito da página que for aberta;
  3. Escolha a opção "Abrir no navegador"; você será direcionado para seu app de internet padrão.