Tentamos recuperar texto desfocado, pixelizado e tarjado. Veja o que voltou.

Resposta curta: se uma captura de tela dá ao atacante o que capturas de tela costumam dar (uma fonte de interface conhecida, um tamanho de texto conhecido, um filtro fácil de adivinhar), então desfoque gaussiano leve e pixelização com blocos pequenos não são redação. No nosso teste de 480 casos, o desfoque com raio de 2 a 4 px devolveu o texto original exatamente em 92 a 100% das vezes. A pixelização de 4 px devolveu em 71% das vezes. Uma sobreposição "transparente" com 20% de opacidade devolveu em absolutamente todos os casos. Salvar o resultado como JPEG depois, como um app de chat faz, quase não ajudou. O único tratamento que não vazou nada foi uma caixa sólida e chapada sobre o texto.
A regra que saiu dos dados é simples. Se o raio do desfoque ou o bloco de pixel for menor que cerca de 0,3 vez o tamanho da fonte em pixels, assuma que o texto pode ser lido de volta. Entre 0,4 e 0,6 vez você ainda vaza de um terço à metade dos caracteres, e para um número de cartão ou uma chave de API isso é uma violação, não um desfoque. A recuperação só caiu ao nível do acaso a partir de 0,8 vez. A essa altura o desfoque é tão pesado que uma caixa sólida fica melhor de qualquer forma.
Tudo aqui é reproduzível. O código, as 480 imagens tratadas e a tabela de resultados estão publicados sob CC-BY; o link está no final.
Por que fizemos isso
"Não desfoque, tarje" é um conselho antigo. O dheera.net defendeu isso em 2014, o Depix mostrou senhas pixelizadas sendo lidas de volta em 2020, e o security.stackexchange repete isso há uma década. O que não encontramos foi uma resposta paramétrica: quanto desfoque é suficiente, em qual tamanho de texto, e o que acontece depois que a imagem passa por um mensageiro que a recomprime. As pessoas escolhem o raio do desfoque no olho. Nós queríamos números.
Método
Amostras. Seis campos do tipo que realmente vaza em telas compartilhadas: um endereço de e-mail, um número de cartão, um IBAN, um número de telefone, uma chave de API (sk_live_...) e o nome de uma pessoa. Cada um renderizado em duas fontes, Arial (proporcional) e Menlo (monoespaçada), em 14 px e 20 px, sobre um fundo de interface escuro, com device pixel ratio 2x, ou seja, uma captura de tela Retina. São 24 imagens de origem.
Tratamentos, dez no total. Desfoque gaussiano com sigma 2, 4, 8 e 12 px. Pixelização com blocos de 4, 8, 12 e 16 px. "Transparente": texto desenhado com 20% de opacidade sobre o fundo, o que algumas ferramentas chamam de máscara suave. E uma caixa sólida na cor do primeiro plano, que chamamos de redação. Cada imagem tratada também foi salva mais uma vez como JPEG com qualidade 80. 24 x 10 x 2 = 480 casos.
O atacante. Assumimos o que uma captura de tela de um produto conhecido entrega de graça: a fonte, o tamanho, a posição do campo e seu conjunto de caracteres (dígitos para um cartão, [a-z0-9._@-] para um e-mail). O atacante conhece ou adivinha o tratamento e sua intensidade. A recuperação é uma busca em feixe (beam search) sobre caracteres: renderizar uma string candidata com a mesma fonte, aplicar o mesmo tratamento, comparar com o alvo, manter os seis melhores prefixos, estender em um caractere, repetir. É a versão rigorosa do que o Depix faz para pixelização, e funciona do mesmo jeito para desfoque e para transparência. Sem aprendizado de máquina, sem GPU. Uma execução completa leva cerca de 25 minutos em um laptop.
Pontuação. CER (taxa de erro de caracteres; 0 é recuperação perfeita, 1 é nada certo) e se a string recuperada coincidiu exatamente. A redação recebe CER 1,0 por construção: todo candidato renderiza a mesma caixa chapada, então não há nada para comparar.
Resultados
Por tratamento

- Transparente (20% de opacidade): CER médio 0,00 · Recuperação exata 100% · Após JPEG q80 0,00 / 100%
- Desfoque sigma 2 px: CER médio 0,00 · Recuperação exata 100% · Após JPEG q80 0,00 / 100%
- Desfoque sigma 4 px: CER médio 0,03 · Recuperação exata 92% · Após JPEG q80 0,10 / 88%
- Pixelização 4 px: CER médio 0,11 · Recuperação exata 71% · Após JPEG q80 0,11 / 71%
- Pixelização 8 px: CER médio 0,49 · Recuperação exata 8% · Após JPEG q80 0,49 / 8%
- Desfoque sigma 8 px: CER médio 0,57 · Recuperação exata 21% · Após JPEG q80 0,64 / 17%
- Pixelização 12 px: CER médio 0,63 · Recuperação exata 21% · Após JPEG q80 0,63 / 21%
- Pixelização 16 px: CER médio 0,83 · Recuperação exata 0% · Após JPEG q80 0,84 / 0%
- Desfoque sigma 12 px: CER médio 0,84 · Recuperação exata 4% · Após JPEG q80 0,87 / 0%
- Redação sólida: CER médio 1,00 · Recuperação exata 0% · Após JPEG q80 1,00 / 0%
A sobreposição transparente é a que menos nos surpreendeu e a que mais nos preocupa. Desenhar texto com 20% de opacidade é apenas desenhá-lo com menos contraste. Um ajuste de níveis o traz de volta, e nossa busca acertou todos os 48 casos. Algumas ferramentas de captura de tela oferecem isso como modo de privacidade. Não é.
Desfoque leve e pixels pequenos são totalmente reversíveis. Desfoque sigma 2 e sigma 4, e pixelização de 4 px, devolveram o texto na maioria das vezes. Não aproximadamente. Exatamente.
JPEG não salva você. A recompressão acrescentou alguns erros ao caso sigma 4 e não mudou nada na pixelização: os blocos são grandes e chapados, que é precisamente o que o JPEG preserva bem.
Por intensidade em relação ao tamanho do texto

Os números absolutos dependem do tamanho da fonte, então a forma útil de lê-los é como razão entre o sigma do desfoque (ou o bloco de pixel) e o tamanho da fonte em pixels:
- até 0,2: Desfoque: CER médio / exata 0,00 / 100% · Pixelização: CER médio / exata 0,01 / 92%
- cerca de 0,3: Desfoque: CER médio / exata 0,07 / 83% · Pixelização: CER médio / exata 0,20 / 50%
- cerca de 0,4: Desfoque: CER médio / exata 0,37 / 33% · Pixelização: CER médio / exata 0,42 / 8%
- cerca de 0,6: Desfoque: CER médio / exata 0,80 / 8% · Pixelização: CER médio / exata 0,40-0,56 / 8-42%
- 0,8 e acima: Desfoque: CER médio / exata 0,87 / 0% · Pixelização: CER médio / exata 0,80-0,87 / 0%
Abaixo de cerca de 0,3 o texto volta. Entre 0,4 e 0,6 ele volta em parte, e "em parte" é a região perigosa: em 46% das execuções com pixelização de 8 px e em 33% das execuções com desfoque sigma 8, pelo menos metade dos caracteres estava correta. Metade de um número de cartão, ou os primeiros doze caracteres de uma chave de API ativa, não é privacidade. Só a partir de 0,8 os resultados ficaram perto do acaso (para um campo só de dígitos, o acaso é um CER em torno de 0,9).
Texto monoespaçado e grande é mais fácil de recuperar

Menlo em 20 px com pixelização de 12 px, blocos com mais da metade da altura do texto, ainda voltou com um CER de 0,02. Fontes de largura fixa dão uma grade à busca; texto maior dá a cada caractere mais pixels para deixar uma assinatura. Isso importa porque terminais, IDEs, visualizadores de log e a maioria das tabelas de administração usam exatamente essa combinação.
Por campo
Números de cartão foram o alvo mais fácil (CER médio 0,22, 64% exatos nos tratamentos de desfoque, pixelização e transparência, sem JPEG): um alfabeto de dez símbolos e comprimento fixo. Endereços de e-mail e chaves de API foram os mais difíceis, com CER em torno de 0,47, porque o espaço de busca por caractere é maior. "Mais difícil" ainda significou que 36% deles voltaram exatamente.
O que isso significa na prática
Tarje, não desfoque, quando o conteúdo é o que importa. Uma caixa sólida foi o único tratamento neste teste que não vazou nada, em todas as fontes, tamanhos e compressões. É também o único cuja segurança não depende de um parâmetro que você precisa acertar.
Se você precisa desfocar, vá pesado e dimensione pelo texto: sigma de pelo menos 0,8 vez o tamanho da fonte, ou blocos de pixel de pelo menos 0,8 vez o tamanho da fonte. O que importa é a razão, não a contagem absoluta de pixels; meça os dois nas mesmas unidades. Para uma fonte de interface de 14 px isso é um sigma de 11 px ou mais, bem mais pesado do que qualquer padrão.
Nunca confie em opacidade. Uma sobreposição transparente é uma mudança de cor, não uma remoção.
Não conte com o mensageiro para terminar o serviço. A recompressão JPEG deixou a pixelização intocada e o desfoque quase intocado.
O desfoque mais seguro é aquele que nunca chega à tela. Qualquer coisa ofuscada depois da captura pode ser atacada a partir dos pixels capturados. Ocultar o valor antes de ele ser desenhado, na página, antes de o compartilhamento ou a gravação começar, remove os pixels de que o ataque precisa. Essa é a abordagem do DataBlur, e é por isso que fizemos este estudo em primeiro lugar.
Limitações
Este é um atacante com fonte conhecida e tratamento conhecido. Isso é realista para capturas de tela de interfaces comuns, em que a fonte e o tamanho são públicos, mas uma fonte incomum eleva a barreira. Não a remove; o atacante ainda pode tentar os candidatos prováveis.
Duas fontes, dois tamanhos, um fundo. Temas claros, diferenças de anti-aliasing e renderização subpixel vão mover os números. Não esperamos que movam muito os limiares, mas não medimos isso.
Nenhum ruído do mundo real além de JPEG q80. Nenhuma foto de tela tirada com celular, nenhuma compressão de vídeo. Codecs de vídeo são um estudo à parte.
O ataque é uma busca em feixe simples. Existem ataques melhores (priors aprendidos, feixes maiores, restrições de dicionário para e-mails e nomes). Nossos números são um piso do que um atacante consegue fazer, não um teto.
Pontuamos a recuperação de texto que o atacante espera encontrar ali. Texto oculto de comprimento desconhecido é mais difícil de localizar, embora a caixa do campo geralmente esteja visível na imagem desfocada de qualquer forma.
Dados e código
Todas as 480 imagens tratadas, a tabela de resultados (results.csv) e o script do experimento (experiment.py, Python com Pillow e NumPy) estão publicados em github.com/yochef17/blur-recovery-study sob CC BY 4.0. Reexecutar a matriz completa leva cerca de 25 minutos em um laptop. Se você estendê-lo, com mais fontes, temas claros ou vídeo, conte para nós: support@datablur.app.
Publicado pela DataBlur. DataBlur é uma extensão de navegador que desfoca ou tarja dados sensíveis em uma página antes de ela ser compartilhada ou gravada. Fizemos este estudo para descobrir quanto da palavra "blur" (desfoque) nessa frase protege alguma coisa. Nenhuma das conclusões depende do produto.