Uma extensão experimental para identificar, analisar e bloquear a execução de códigos e a coleta de eventos via JavaScript em seu navegador.
Existem projetos incríveis como o Lightbeam, NoScript, ScriptSafe, uBlock Origin, HTTPS Everywhere e diversos outros. Todos possuem a proposta de identificar e/ou impedir a execução de códigos e requisições questionáveis.
Tais ferramentas são vitais, mas inevitavelmente precisamos fazer concessões para conseguir acessar muitos sites já que a utilização de JavaScript é massiva na web. Ao acessar por exemplo o Google Tradutor, utilizando um combo de 3 extensões (HTTPS Everywhere, uBlock Origin e ScriptSafe) com a Luminous temos o seguinte resultado após um breve momento de utilização do website:
É sobre este número (7,6 mil) que estamos perdidos e de mãos atadas, é alí que não sabemos o que acontece e ainda não temos a liberdade de decidir o que pode e o que não pode ser executado. Este é o principal objetivo do projeto, preencher esta lacuna e conseguir ver e controlar o que acontece. Como efeito colateral acabamos tendo também uma ferramenta interessante que ajuda no desenvolvimento de códigos em JavaScript ao nos dar visibilidade sobre o que está acontecendo.
Instale a extensão e acesse a nossa página de demonstração para experimentar e entender melhor o seu funcionamento:
Veja algumas capturas de tela aqui.
Guias são documentos sobre assuntos muitos específicos onde podemos ir fundo nos detalhes e encontrar facilmente as informações que estamos procurando. Veja aqui todos os guias.
Colabore escrevendo algum guia sobre assuntos relacionados ao projeto.
Conte aos seus amigos, familiares e colegas de trabalho sobre como a extensão foi utilizada para melhorar a sua experiência na web e os ensine a utilizá-la também!
Descobriu que algum site estava invadindo a sua privacidade? Conseguiu bloquear eventos que não desejava? Conseguiu facilitar o desenvolvimento do seu código ou a depuração de erros? Grave um video, prepare uma palestra, escreva um artigo ou qualquer coisa do gênero contando como foi feito, explicando como a extensão o ajudou e mostrando as possibilidades.
Traduza os arquivos .md
encontrados dentro do diretório doc/
e os arquivos .json
dentro do diretório _locales/
para o seu idioma e nos ajude a atingir mais pessoas!
Teve problemas ao acessar algum site por causa da extensão? Ficou lento? Causou erros? O site parou de funcionar? Nem todos os eventos foram identificados? Abra uma issue e conte pra gente sobre o que aconteceu.
Abra uma issue se algo não funcionou como você esperava em algum navegador. Queremos que tudo funcione bem em todos os navegadores possíveis!
Não temos a interface mais bonita e amigável possível. Discussões e propostas sobre uma nova interface ou melhorias na já existente (html/interface-sample.html
) serão muito bem-vindas! Não subestime o poder desse tipo de colaboração: better_errors#6 - better_errors#22
Exemplo 1: Quanto mais cedo conseguirmos injetar o código nos websites e quanto menos recursos utilizarmos para processar as informações, mais execuções seremos capazes de identificar e melhor será a nossa experiência ao ter uma extensão que não deixe a navegação lenta.
Olhe por exemplo para a nossa página de demonstração (html/demos/detections/index.html
):
(function() { setTimeout(function() {
// JavaScript code...
}, 100); })();
Esse delay de 100 milessegundos existe pois sem ele o código é executado rápido demais e não conseguimos interceptá-lo. Como podemos melhorar isso para não precisarmos desse delay ou então conseguir diminuí-lo?
Exemplo 2: Capturamos apenas um pedaço da função interceptada, pois ela pode ser muito grande e deixar a leitura das informações lenta (js/content/interceptor.js
):
listener: ('' + listener).slice(0, 400)
Como podemos melhorar isso? Essa é a melhor maneira de lidar com este problema?
Exemplo 3: A maneira que encontramos de passar mensagens do contexto do documento para o contexto da extensão foi realizando o parser dos dados em JSON lendo um elemento HTML (js/content/readers/data.js
):
render_data(
JSON.parse($(data_element).html()),
tab_id
);
Existem alternativas? Fazer o parse das informações constantemente é a melhor opção?
Começamos com uma ideia básica: identificar e bloquear eventos. Podemos expandir essa ideia, alguns pensamentos que já surgiram:
Interceptamos apenas chamadas para o addEventListener
e o handleEvent
. Não seria interessante interceptarmos também chamadas para o XMLHttpRequest
e outros?
Não estamos interceptando eventos definidos inline (<a onclick="someAction()">
), não seria interessante fazer isso?
Hoje podemos bloquear os eventos por domínio: "Bloquear a execução de mouseover
no domínio somesite.com
". Não seria interessante ter regras mais elaboradas e bloquear um evento apenas se o seu alvo for um tipo de elemento X ou o código executado for de acordo com alguma expressão regular?
Este é um projeto experimental que cresceu de forma descontrolada, não temos um padrão definido de nomenclatura, uma forte organização baseada em algum design pattern ou testes automatizados. Discussões para melhorar a qualidade do código nesse sentido serão muito bem-vindas!
Não interceptamos codigos inline (<a onclick="someAction()">
).
Um código pode ser executado antes de conseguirmos injetar o interceptador. É raro, mas possível.
Alguns sites com uma quantidade absurda de eventos JavaScript pode deixar o navegador lento por conta da coleta de dados sobre as interceptações realizadas.
No Mozilla Firefox e derivados, alguns sites que utlizam Service Workers (como o WhatsApp Web) podem bloquear o código de interceptação por conta de um bug na interceptação dos headers com as diretrizes de Content-Security-Policy. A solução alternativa atual consiste em recarregar o Service Worker:
about:debugging#workers
Clique em unregister no Service Worker do site desejado:
js/background
:
js/background/set_current_tab.js
: Responsável por injetar o ID da tab atual no documento.
js/background/set_response_headers.js
: Responsável por alterar o header de Content-Security-Policy das requisições.
js/background/update_badge.js
: Responsável por atualizar o contador mostrado no ícone da extensão.
/content/injections
:
/content/injections/data.js
: Responsável por injetar o elemento HTML que armazenará os dados coletados das interceptações.
/content/injections/interceptor.js
: Responsável por injetar o código que executará as interceptações de fato no documento.
/content/injections/options.js
: Responsável por injetar o elemento HTML que armazenará os opções definidas pelo usuário./content/readers
:
/content/readers/data.js
: Responsável por ler os dados no elemento HTML do documento que armazena os detalhes coletados das interceptações e repassa-los à extensão./content/injections_controller.js
: Responsável por tomar decisões sobre a injeção de códigos.
/content/interceptor.js
: Responsável por interceptar execuções de códigos JavaScript no contexto do documento e coletar detalhes sobre elas.
Responsáveis por renderizar e cuidar das interações feitas no pop-up que é aberto ao clicar no ícone da extensão:
html/popup/popup.html
html/popup/templates/counters.html
html/popup/templates/options.html
js/popup/popup.js
css/popup/popup.css
Responsáveis por renderizar e cuidar das interações feitas nas páginas de configurações:
html/settings/*.html
js/settings/*.js
css/settings/*.css
js/utils/colors.js
: Função utilizada para determinar a cor exibida com base no valor do contador.js/utils/number.js
: Função utilizada para formatar o número de acordo com seu tamanho.vendor/bootstrap
: Bootstrap: biblioteca de componentes front-end
vendor/jquery
: jQuery JavaScript Libraryvendor/mustachejs
: Minimal templating with {{mustaches}} in JavaScriptvendor/tippyjs
: A lightweight, vanilla JS tooltip libraryEste projeto está licenciado sob a GPLv3.
Não há nenhum tipo de organização para o recebimento de doações no momento. Veja nosso guia sobre "como colaborar" para outras maneiras de contribuição. Se deseja realmente realizar uma doação, eis algumas fundações incríveis que vão de encontro com os temas abordados neste projeto que você pode ajudar: