Como hackear o Firefox para contornar a falta de suporte a WebUSB
(github.com/ArcaneNibble)- Este proof-of-concept mostra que uma página web pode se comunicar com um dispositivo USB específico mesmo sem WebUSB, fazendo um Raspberry Pi Pico agir como uma chave de segurança U2F e aproveitando o suporte já existente do navegador a chaves de segurança
- O Pico não executa funções reais de segurança; em vez disso, oculta dados arbitrários no key handle da mensagem
U2F_AUTHENTICATEe na área de assinatura ECDSA para implementar controle do LED e leitura do estado do pinoGP22 - O key handle de U2F foi projetado como um blob opaco de dados pertencente ao dongle de segurança, e esse recurso — que permite a dongles baratos lidar com registros em vários sites com memória limitada — é explorado para ocultação de dados
- Esse método não é uma vulnerabilidade de acesso a dispositivos USB arbitrários; ele só funciona em dispositivos que quebram deliberadamente as regras, mas o problema do modelo de segurança do USB, em que um dispositivo USB malicioso pode se comportar como teclado ou mouse, continua existindo
- O ponto da discussão vai além de o Firefox ter ou não suporte a WebUSB e se expande para como criar uma plataforma de computação saudável e um ecossistema que tanto desenvolvedores quanto usuários possam entender e controlar
Demo de acesso a dispositivo USB sem WebUSB
- É um proof-of-concept que mostra uma forma de uma página web se comunicar com um dispositivo USB sem depender da controvérsia política em torno do WebUSB nem de exigências de consentimento do usuário
- A demonstração rápida funciona gravando
u2f-hax.uf2em uma versão RP2040 do Raspberry Pi Pico e abrindoindex.htmlem localhost ou outro secure context - Os botões
On!eOff!da página alternam o LED do Pico - O estado do pino
GP22é atualizado periodicamente na página e pode ser testado fazendo curto com o pad GND adjacente usando um fio ou metal
Como funciona: fingindo ser uma chave de segurança U2F
- O Pico é emulado como um dongle U2F, ou seja, uma chave física de segurança para autenticação em duas etapas
- Em vez de executar funções reais de segurança, ele oculta dados arbitrários dentro da mensagem
U2F_AUTHENTICATE- Os dados ficam no key handle e na área de assinatura
- Se o key handle começar com
0xfeedface, o Pico trata isso como confirmação imediata de presença do usuário e retorna os dados
- Do ponto de vista do navegador, isso usa a funcionalidade já existente de interação com chaves de segurança
Por que o key handle de U2F pode ser explorado
- O key handle do U2F é, conceitualmente, um blob opaco de dados pertencente ao dongle de segurança
- O fluxo típico é o seguinte
- Como resultado do registro, o dongle retorna um key handle
- A relying party armazena esse valor sem alterações
- Na autenticação, esse mesmo valor é enviado de volta ao dongle de segurança
- Esse recurso está ligado a um projeto que permite a dongles baratos com memória limitada lidarem com registros em muitos sites
- O dongle armazena internamente uma chave mestra de criptografia única
- Ao registrar um novo site, ele cria um par de chaves pública/privada e retorna a chave pública
- Ele retorna como key handle o valor da chave privada criptografada com a chave mestra
- Na autenticação, ele descriptografa com a chave mestra o key handle recebido e usa a chave privada
- Para não especificar um algoritmo interno, o key handle é tratado como opaco, e essa propriedade é usada para ocultar dados arbitrários
Os dados retornados são disfarçados de assinatura ECDSA
- Para enviar dados de volta, dados arbitrários são ocultados como se fossem uma assinatura ECDSA
- Uma assinatura ECDSA é uma tupla de dois números
(r, s), e cada número é calculado com base na ordemndo base point da curva elíptica - Números dentro do intervalo da ordem do base point secp256r1 são empacotados em ASN.1
- Em alguns casos, é possível distinguir se aquilo é de fato uma assinatura ECDSA calculada corretamente, mas componentes que não sejam a relying party não têm motivo forte para fazer mais do que a validação básica
- Há diferenças de comportamento entre navegadores
- O Chrome aparentemente verifica se os números da assinatura estão no intervalo de
0an - O Firefox nem sequer faz essa verificação de intervalo
- O Chrome aparentemente verifica se os números da assinatura estão no intervalo de
- Para passar de forma confiável pela checagem básica do Chrome, o primeiro byte de cada número é desperdiçado com
0x7f- Assim, o número sempre fica positivo e menor que
n - A pilha de software até o JavaScript do navegador entrega esses números “válidos o suficiente” sem alterações
- Assim, o número sempre fica positivo e menor que
Se isso é uma vulnerabilidade e o modelo de segurança do USB
- Essa técnica não é uma vulnerabilidade de acesso a dispositivos USB arbitrários
- Ela só funciona em dispositivos que quebram deliberadamente as regras e, em essência, são dispositivos tornados vulneráveis de propósito
- Ainda assim, na maioria das plataformas, o modelo de segurança em torno de dispositivos USB é geralmente questionável
- Ao conectar um dispositivo USB malicioso, ele pode realizar ações que o usuário conseguiria fazer por meio de algo como teclado ou mouse
- Não se deve conectar dispositivos desconhecidos arbitrários a computador, celular ou afins
Questionamentos sobre plataforma e ecossistema
- O objetivo do proof-of-concept vai além de um interesse pessoal de “porque dá para fazer” e busca expor o estado atual das plataformas de computação
- Do ponto de vista de quem fabrica gadgets, o ideal é que o usuário final consiga usar um novo dispositivo com o mínimo possível de atrito
- Hoje existe um desalinhamento entre o que o usuário intuitivamente espera que seja possível no ecossistema de computadores e gadgets e o que de fato é possível
- Espera-se que uma “chave de segurança” pareça um produto bem empacotado e de finalidade única, mas na prática ela pode executar código arbitrário, parecer qualquer coisa e realizar comportamentos arbitrários
- USB Rubber Ducky e O.MG Cable também são exemplos que tocam nesse problema
- O caráter “Universal” do USB traz vantagens e desvantagens
- Nem pessoas nem computadores têm uma boa forma de distinguir com facilidade e confiabilidade se um dispositivo USB age contra o interesse do usuário, se o ajuda ou se é resultado de maior poder e comportamento emergente
- A Web é a forma mais fácil de entregar software que será executado no computador de outra pessoa
- Desenvolvedores precisam aprender menos detalhes de cada plataforma de destino, mas ao mesmo tempo também aprendem menos sobre os costumes e expectativas de cada plataforma
- A discussão precisa ir além de “por que o Firefox não implementa WebUSB” ou “será que vai perder mais terreno para o Chrome” e se mover na direção de cultivar intencionalmente plataformas saudáveis em toda a computação, incluindo desktops, notebooks, tablets, celulares, IoT e casa inteligente
1 comentários
Comentários do Hacker News
O Firefox não oferece suporte à capacidade de se comunicar com dispositivos USB arbitrários, mas o Chrome tem WebUSB para isso.
No entanto, o Firefox também oferece suporte à comunicação com chaves de segurança U2F via USB.
Este projeto é uma tentativa de fazer um microcontrolador fingir ser uma chave de segurança U2F para se comunicar com ele via USB no Firefox.
Com a JavaScript Credentials API(https://developer.mozilla.org/en-US/docs/Web/API/Credential_...) e alguns truques, ele envia dados e recebe respostas.
Ainda assim, pode ser usado para criar dispositivos customizados que uma página web consegue usar sem prompt de consentimento.
Customizar teclados com firmware QMK/Via via WebUSB é quase um pesadelo.
Para o navegador se comunicar com o firmware, na prática é preciso tornar um dispositivo
/dev/hidrawlegível por todo mundo, o que abre espaço para todo tipo de brincadeira de keylogging.O modo de uso é bem desconfortável, e as ferramentas de customização offline também são todas baseadas em Electron, então não há uma grande vantagem.
A alternativa minimamente razoável é criar no site o layout de teclado desejado como um JSON de template, baixar o JSON resultante e então gravar o firmware no teclado com uma ferramenta de flashing com permissões de sudo.
Ainda assim, seria bom se houvesse um método menos desconfortável.
main()em execução.Parece que teclados poderiam fazer algo parecido.
Bastaria o sistema de arquivos gerar erro ao gravar um JSON inválido e ter atributos de segurança no sistema de arquivos emulado para permitir escrita apenas ao administrador.
Não seria preciso sudo; bastaria aprovar o prompt de permissão ao baixar ou copiar a nova configuração para a unidade flash virtual.
Parece que pelo menos o Caps Lock também pode ser configurado por JavaScript, então, na prática, isso vira um barramento de comunicação de 1 bit de largura.
Com ferramentas comuns do SO, poderia chegar a 3 bits.
O ponto central do modelo de permissões é que a família de navegadores intermedeia o acesso ao hardware.
Naturalmente, para o navegador fazer isso, é preciso conceder acesso ao hardware desde o início.
Dá para não confiar no navegador como administrador da camada de abstração de hardware, mas esse é o modelo que o Via espera.
Não sei por que isso seria mais “desconfortável” do que dar ao navegador permissão para câmera, microfone e leitura de armazenamento.
Mesmo em um Chromebook corporativo gerenciado e bloqueado, dá para acessar https://usevia.app e mexer em um teclado QMK sem problemas; obviamente, nesse dispositivo não consigo tocar em nenhum nó de
/dev.QMK é todo via flashing manual.
Ainda assim, fiquei surpreso com o quanto é fácil customizar layout, camadas e iluminação em código, muito por causa do suporte da comunidade.
Não é tão conveniente quanto o Via, mas ainda tem um editor gráfico de keymap, compila o firmware para você e é bem menos pesado.
Minha experiência foi boa em placas da Keeb.io.
Este fio de comentários é interessante porque mistura pessoas que usam WebUSB dizendo como ele é bom e pessoas que não usam sem entender por que ele é necessário.
Pessoalmente, achei excelente.
A maioria dos utilitários WebUSB que uso também existe como app instalável, mas eu os uso tão raramente que a versão web é muito mais fácil do que instalar, atualizar e depois executar um app.
Ter um app a menos para instalar também é uma vantagem.
Achei que isso seria popular entre pessoas cansadas de ter que instalar um app para cada coisa.
Por isso é uma faca de dois gumes.
Conveniência e segurança não combinam muito bem.
É útil e fácil, mas também é bom demais para o surgimento de vulnerabilidades.
O inchaço da web precisa parar.
O navegador não deve se tornar uma pia de cozinha universal com tudo que qualquer pessoa da indústria de tecnologia quiser colocar nele.
Instalar aplicações nativas também não é algo tão difícil assim.
Tecnicamente não é USB, é HID, mas a ideia é parecida.
Fugindo um pouco do tema, mas a maior parte desta discussão parece ser sobre WebUSB em geral, mais do que sobre o post original
Claro que o hack do post original em si é bem legal
Por um lado, WebUSB é realmente necessário; por outro, eu realmente não quero que WebUSB seja entregue a usuários comuns
Na prática, pop-ups de consentimento não funcionam, e as pessoas aprovam qualquer coisa sem perceber
Elas dizem “não cliquei em nada”, mas aí você acaba afastando 50 notificações push de spam e removendo permissões de push de uma dúzia de sites de “notícias”
Sinceramente, gosto em certa medida do modelo de permissões ao estilo do Internet Explorer
Era o tipo de abordagem em que, para ativar determinados recursos, era preciso marcar o site como “confiável”
Era difícil de encontrar, levava um tempo, era um pouco confuso, e um pop-up modal no estilo do sistema exibia um grande ícone de alerta bem assustador
Se APIs perigosas como WebUSB e WebBluetooth exigissem passar pelo procedimento de marcar o site como “confiável”, muito menos gente as ativaria por engano
A experiência do usuário ainda seria melhor do que instalar um app nativo, e o sandboxing viria de brinde, então essa troca parece valer a pena
O usuário idoso médio não faz a menor ideia do que sejam notificações web
Com o tempo, acaba ativando por engano notificações de sites suspeitos e acredita de verdade em notificações de spam web no celular do tipo “HELLO YOUR PHONE HAS VIRUS DOWNLOAD "CLEANER APP" TO FIX BEFORE PHONE DIE”
Algumas pessoas parecem ter algum superpoder para estragar coisas
Se você não tornar algo literalmente impossível, elas inevitavelmente encontrarão um jeito de fazê-lo por engano
Seguem guias para mudar configurações que não entendem, executam recursos que não entendem e concedem acessos que não entendem
Isso acontece por mais que você complique o processo, coloque alertas e tente impedir esse tipo de burrice
O problema é que também há pessoas que sabem o que estão fazendo e usam essas coisas de propósito
Essas pessoas podem apreciar recursos poderosos que nunca deveriam ser dados a um idiota
Mas, ao expor esse poder, é angustiante que, na prática, seja difícil evitar uma enxurrada de gente fazendo besteira
Um grande problema é não entender de verdade que muitos usuários não entendem absolutamente nada do que estão fazendo
O Google não entende como projetar software seguro para essas pessoas
Procedimentos incômodos parecem sem sentido, mas muitas vezes têm um objetivo claro
Confirmar se a intenção do usuário é firme
A Apple implementou recentemente algumas APIs web de modo que elas só funcionem quando o site está instalado, e isso parece uma estratégia que entende design para pessoas
Ela permite acesso a recursos úteis de PWA, mas não deixa qualquer site usá-los arbitrariamente
Há um passo adicional que uma pessoa comum consegue entender
Um PWA instalado continua visível na tela inicial, servindo como um lembrete visível da permissão concedida e como um sinal claro de que o usuário queria aquele acesso
Muita gente precisa interagir com dispositivos, e hoje apps distribuídos por App Stores fechadas são, muitas vezes, praticamente a única opção
Para distribuir a mais pessoas uma forma de acessar dispositivos que perderam suporte oficial, WebUSB é de longe o caminho mais fácil
Em um mundo alternativo em que o Chrome não oferecesse suporte, usuários comuns teriam que conseguir instalar e executar [python or other scripting language]
Se o desenvolvedor fosse realmente dedicado, talvez tivesse que oferecer um app de desktop ou passar pelo processo longo e caro de submissão à App Store
Acredito que seja possível criar uma UI segura para WebUSB, e também não consigo pensar facilmente em quais dispositivos conectados pelo usuário médio poderiam ser comprometidos
Não deve ser possível tomar controle de teclado ou mouse (HID), armazenamento, Wi-Fi, áudio, smartcards ou dispositivos U2F por WebUSB
Mas ele é muito útil para impressoras de etiquetas proprietárias, brinquedos e dispositivos diversos, e para programar e gravar microcontroladores
São fáceis e convenientes de usar, mas também tornam fácil conceder por engano a terceiros não confiáveis um acesso muito amplo
Dar permissão a uma página deveria ser, como foi dito, um fluxo iniciado explicitamente pelo usuário no painel de permissões
O mesmo vale para aplicações desktop em sandbox
Se algum app quiser gravar a tela continuamente, deve obter essa permissão explicitamente no painel de controle de permissões
Ele não deveria poder abrir uma caixa de diálogo modal que leve as pessoas simplesmente a clicar em “yes”
Em muitos casos, as pessoas não entendem tecnicamente o que está sendo solicitado a elas
USB Serial é realmente excelente
Finalmente acaba com aqueles apps Electron chatos feitos para uma única finalidade
Agora existem ferramentas para configurar dispositivos pelo navegador, e isso é muito bom
Basta olhar para o ESPHome e centenas de projetos baseados nele, Betaflight, ELRS, Flipper
Entendo que o suporte do WebKit seja limitado, já que é desenvolvido pela Apple, e também entendo que eles sejam cautelosos se forem permitir acesso a periféricos
Mas o Firefox é diferente
O Firefox sempre teve uma falta grave de suporte a “conexão” com hardware e há muito tempo deixou de ser amigável para desenvolvedores, então acabei parando de usá-lo
A justificativa para não dar suporte é que apenas o consentimento do usuário não é suficiente para acessar dispositivos, mas isso não faz sentido
Poderiam ao menos ter colocado isso atrás de uma flag de desenvolvedor
O Blink provou que dá para tornar isso seguro
Parece teimosia sem motivo, e eles parecem não enxergar casos de uso que tornariam o navegador útil
https://developer.mozilla.org/en-US/docs/Web/API/Serial
https://mozilla.github.io/standards-positions/
Credenciais U2F deveriam ser impossíveis de sofrer phishing
Isso porque a API U2F do navegador inclui o nome do domínio na solicitação ao token
Mas, usando WebUSB, um site conseguia solicitar um token para um nome de domínio arbitrário
Como U2F e WebUSB exibiam caixas de consentimento do usuário bastante parecidas, era praticamente impossível evitar que alguns usuários se confundissem
Por incrível que pareça, a solução do Google foi colocar muitos dispositivos em uma lista de bloqueio do WebUSB
Agora, quem fabrica dispositivos U2F precisa pedir ao Google para adicioná-los à lista de bloqueio sempre que lança um novo produto
Todo mundo gosta da ideia de o navegador ser uma sandbox segura que permite executar código não confiável, mas não entendo por que querem abrir tantos buracos nessa sandbox
[1] https://www.yubico.com/support/security-advisories/ysa-2018-...
[2] https://github.com/WICG/webusb/blob/main/blocklist.txt
Não acho que valha a pena assumir o risco de fingerprinting em benefício de algumas dezenas de usuários finais que não teriam de baixar um app Electron para interagir com hardware físico
Implementar um recurso e trancá-lo atrás de um toggle de desenvolvedor é loucura
É desperdiçar centenas de horas de desenvolvimento que poderiam ser usadas em algo útil, para expor um recurso que ninguém vai encontrar de qualquer forma
Como desenvolvedor, não me importo se essas APIs exclusivas do Chrome continuarem só no Chrome
De todo modo, é preciso manter um navegador Chromium de prontidão para quando algum site realmente quebrar no Firefox, então é só usá-lo para trabalhos com Web USB
É uma demonstração tecnológica legal, mas não é algo que um navegador deveria fazer
O fato de ninguém ter adicionado funcionalidade WebUSB como extensão do Firefox também parece mostrar que, mesmo para as pessoas que usam esse recurso, ele não vale o tempo de desenvolvimento
Questões de privacidade e segurança vêm sendo levantadas
Web Serial não é um padrão web e não pode se tornar um até que Mozilla ou Apple considerem esses problemas resolvidos
O Google não pode transformá-lo sozinho em um padrão web; padrões exigem consenso
A discussão da Mozilla está aqui: https://github.com/mozilla/standards-positions/issues/336
A discussão do WebKit está aqui: https://github.com/WebKit/standards-positions/issues/199
Acho difícil imaginar abandonar o Firefox para navegação web por causa de webusb
Tem que ser software que possa ser baixado e que não dependa de servidores externos
Dito isso, se o dispositivo já depende dos servidores dessa empresa para funcionar, é bom não precisar baixar e confiar em um software
Talvez seja até uma coisa boa não permitir o uso de portas USB em código baseado no navegador
Porque não preciso mais abrir uma VM Windows para executar atualizações de firmware ou ferramentas utilitárias de fabricantes de equipamentos de áudio que dão suporte a isso, como a Novation
O WebUSB deveria permitir a mesma coisa para mais tipos de dispositivos, mas obviamente precisa haver um mecanismo adequado de permissões
Para quem faz flashing de dispositivos com frequência, o benefício é claro
Mas usuários comuns, ou seja, os outros cerca de 3 bilhões de pessoas, não se importam nem um pouco
Abrir buracos na sandbox por causa deles é, na melhor das hipóteses, imprudente
A solução pode ser uma ferramenta separada dedicada a esse uso, talvez até um navegador separado
Algo como um Flash Browser
Ele poderia incluir ferramentas extras para ajudar nessa tarefa
Como listas de permissão ou bloqueio pré-configuradas, favoritos para ferramentas comuns de flashing e materiais de referência
Daria para criar uma experiência melhor do que enfiar WebUSB cru no navegador à força
Entendo a controvérsia e as críticas em torno desse “padrão”, mas, quando usei para fazer flashing do GrapheneOS em um celular Pixel, foi a instalação de sistema operacional mais agradável, fácil e rápida que já fiz em qualquer dispositivo
Foi literalmente no nível de conectar, clicar e sair usando
A parte de criptografar a chave privada com uma chave “mestre” e retornar a chave privada criptografada como handle de chave é surpreendente
Deve funcionar de fato
Mas dar a um atacante infinitas oportunidades de tentar descriptografar a chave privada que ele tem em mãos parece algo que um dia vai sair pela culatra; mas o que eu sei?
Por exemplo, outra abordagem seria criar a chave privada a partir do handle de chave por meio de derivação determinística de chave
Um atacante poderia fazer força bruta nisso também, assim como faria com a chave específica do site criptografada e armazenada no handle de chave
O ponto central é que um autenticador sem estado é, por definição, determinístico globalmente, ou seja, em relação ao segredo e a todos os sites
Dado um par de entrada-saída, é possível fazer força bruta do segredo interno
A solução é tornar esse estado interno grande o suficiente para que isso seja computacionalmente inviável
Fico curioso sobre qual é a controvérsia política em torno do WebUSB
É uma API exclusiva do Blink criada pelo Google, e a Mozilla e a Apple a rejeitaram por motivos de privacidade e segurança
Sem duas implementações independentes, ela não pode se tornar um padrão da Web, e o Google não conseguiu convencer ninguém fora do Google a implementá-la
Mesmo assim, em vários sites parece que Firefox e Safari é que “não conseguem dar suporte” a ela
“This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track.”
— https://wicg.github.io/webusb/
“WebKit declined to implement several APIs, including WebUSB, due to concerns over fingerprinting”
“We have previously stated privacy concerns, thus the concerns: privacy label. We agree with Mozilla's security concerns raised in their standards position issue, thus the concerns: security label.”
— https://github.com/WebKit/standards-positions/issues/68
“Because many USB devices are not designed to handle potentially-malicious interactions over the USB protocols and because those devices can have significant effects on the computer they're connected to, we believe that the security risks of exposing USB devices to the Web are too broad to risk exposing users to them or to explain properly to end users to obtain meaningful informed consent. It also poses risks that sites could use USB device identity or data stored on USB devices as tracking identifiers.”
— https://mozilla.github.io/standards-positions/#webusb
O navegador já consegue acessar os dispositivos USB de que precisa por meio das interfaces comuns do sistema operacional
Teclado e mouse são exemplos óbvios
Não vejo por que algum site deveria precisar de acesso direto separado
Os casos de uso parecem se resumir a dar acesso a programadores Web que têm preguiça de escrever uma aplicação independente, ou a oferecer mais uma forma de rastrear usuários
Não quero confiar em nenhum dos dois
Não confio nem no Google e na Mozilla a ponto de dar esse tipo de acesso, muito menos em um desconhecido qualquer que criou um site
Nem tudo precisa ser acessível pela Web
Não sei onde a linha deve ser traçada, mas, para mim, acesso a USB passa dessa linha
Normalmente é uma disputa vencida por quem quer o recurso agora
Porque falhas de segurança parecem problemas hipotéticos até serem exploradas no mundo real
Quanto mais isso acontece, mais profunda fica a dependência do Chrome
Eu também não quero isso