Cómo hackear Firefox para resolver la falta de soporte de WebUSB
(github.com/ArcaneNibble)- Este proof-of-concept muestra que una página web puede comunicarse con un dispositivo USB específico incluso sin WebUSB, haciendo que una Raspberry Pi Pico se comporte como una llave de seguridad U2F y aprovechando el soporte existente del navegador para llaves de seguridad
- La Pico no realiza funciones de seguridad reales; oculta datos arbitrarios en el key handle y en el área de firma ECDSA del mensaje
U2F_AUTHENTICATEpara implementar el control del LED y la lectura del estado del pinGP22 - El key handle de U2F está diseñado como un blob de datos opaco propiedad del dongle de seguridad, y una función pensada para permitir que dongles de bajo costo manejen registros en múltiples sitios con memoria limitada se abusa para ocultar datos
- Este método no es una vulnerabilidad que permita acceder a dispositivos USB arbitrarios, y solo funciona con dispositivos que rompen las reglas intencionalmente, pero el problema del modelo de seguridad de USB, donde un dispositivo USB malicioso puede actuar como teclado o mouse, sigue existiendo
- El debate se extiende más allá de si Firefox soporta WebUSB, hacia cómo crear una plataforma de cómputo saludable y un ecosistema que tanto desarrolladores como usuarios puedan entender y controlar
Demo de acceso a dispositivos USB sin WebUSB
- Es un proof-of-concept que muestra una forma en que una página web puede comunicarse con un dispositivo USB sin la controversia política relacionada con WebUSB ni requisitos de consentimiento del usuario
- La demo rápida se ejecuta cargando
u2f-hax.uf2en la versión RP2040 de la Raspberry Pi Pico y abriendoindex.htmlen localhost o en otro secure context - Los botones
On!yOff!de la página alternan el LED de la Pico - El estado del pin
GP22se actualiza periódicamente en la página, y se puede probar haciendo un corto con un cable o metal contra el pad GND adyacente
Cómo funciona: hacerse pasar por una llave de seguridad U2F
- La Pico se emula como un dongle U2F, es decir, como una llave de seguridad física de autenticación de segundo factor
- En lugar de realizar funciones de seguridad reales, oculta datos arbitrarios dentro de mensajes
U2F_AUTHENTICATE- Los datos van en el key handle y en el área de firma
- Si el key handle empieza con
0xfeedface, la Pico lo trata de inmediato como si se hubiera confirmado la presencia del usuario y devuelve los datos
- Desde el punto de vista del navegador, esto usa una funcionalidad existente para interactuar con una llave de seguridad
Por qué se puede abusar del key handle de U2F
- El key handle de U2F es, conceptualmente, un blob de datos opaco propiedad del dongle de seguridad
- El flujo típico es el siguiente
- Como resultado del registro, el dongle devuelve un key handle
- El relying party lo almacena tal cual
- Durante la autenticación, vuelve a pasar el mismo valor a la llave de seguridad
- Esta función está vinculada con un diseño que permite que dongles de bajo costo con memoria limitada manejen registros en muchos sitios web
- El dongle almacena internamente una clave criptográfica master única
- En un nuevo registro, crea un par de clave pública/privada y devuelve la clave pública
- Devuelve como key handle el valor de la clave privada cifrada con la clave master
- Durante la autenticación, descifra con la clave master el key handle recibido y usa la clave privada
- Para no especificar un algoritmo interno concreto, el key handle se trata como opaco, y esta propiedad se usa para ocultar datos arbitrarios
Los datos devueltos se empaquetan como una firma ECDSA
- Para devolver los datos, se ocultan datos arbitrarios como si fueran una firma ECDSA
- Una firma ECDSA es una tupla de dos números
(r, s), y cada número se calcula respecto den, el orden del punto base de la curva elíptica - Los números dentro del rango del orden del punto base de secp256r1 se empaquetan como ASN.1
- En algunos casos puede ser posible distinguir si realmente es una firma ECDSA calculada correctamente, pero los componentes que no son el relying party no tienen una razón fuerte para hacer más que una validación básica
- Hay diferencias de comportamiento entre navegadores
- Chrome parece verificar que los números de la firma estén dentro del rango de
0an - Firefox ni siquiera hace esa verificación de rango
- Chrome parece verificar que los números de la firma estén dentro del rango de
- Para pasar de forma confiable las validaciones básicas de Chrome, se desperdicia el primer byte de cada número con
0x7f- Así el número siempre es positivo y menor que
n - La pila de software hasta el JavaScript del navegador transmite estos números “suficientemente válidos” tal cual
- Así el número siempre es positivo y menor que
Si es una vulnerabilidad de seguridad y el modelo de seguridad de USB
- Esta técnica no es una vulnerabilidad que permita acceder a dispositivos USB arbitrarios
- Solo funciona con dispositivos que rompen las reglas intencionalmente; en esencia, es un dispositivo hecho vulnerable a propósito
- Sin embargo, en la mayoría de las plataformas, el modelo de seguridad alrededor de los dispositivos USB suele estar en un estado cuestionable
- Si se conecta un dispositivo USB malicioso, puede realizar acciones que el usuario podría hacer mediante dispositivos como un teclado o un mouse
- No se deberían conectar dispositivos desconocidos arbitrarios a computadoras, teléfonos u otros equipos
Cuestionamiento sobre plataformas y ecosistemas
- El objetivo del proof-of-concept va más allá de un “porque puedo” personal: busca exponer el estado actual de las plataformas de cómputo
- Desde el punto de vista de un fabricante de widgets, se quiere que el usuario final pueda usar un dispositivo nuevo con la menor fricción posible
- En el ecosistema actual de computadoras y widgets existe un desajuste entre lo que los usuarios esperan intuitivamente que sea posible y lo que realmente lo es
- Se espera que una “llave de seguridad” parezca un producto de propósito único bien empaquetado, pero en realidad puede ejecutar código arbitrario, presentarse de cualquier forma y realizar acciones arbitrarias
- USB Rubber Ducky y O.MG Cable también son ejemplos que tocan este problema
- La naturaleza “Universal” de USB trae ventajas y desventajas
- Ni las personas ni las computadoras tienen una forma buena y confiable de distinguir fácilmente si un dispositivo USB va contra los intereses del usuario, si lo ayuda, o si es el resultado de fuerzas más grandes y comportamientos emergentes
- La Web es la forma más fácil de entregar software que se ejecutará en la computadora de otra persona
- Los desarrolladores tienen menos necesidad de aprender los detalles de todas las plataformas objetivo, pero al mismo tiempo también aprenden menos sobre las costumbres y expectativas de cada plataforma
- La discusión debe moverse más allá de “por qué Firefox no implementa WebUSB” o “si quedará aún más relegado frente a Chrome”, hacia cultivar deliberadamente plataformas saludables en todo el cómputo, incluidos desktops, laptops, tablets, teléfonos, IoT y hogares inteligentes
1 comentarios
Opiniones de Hacker News
Firefox no admite la función de comunicarse con dispositivos USB arbitrarios, pero Chrome tiene WebUSB para eso.
Sin embargo, Firefox sí admite la comunicación con llaves de seguridad U2F por USB.
Este proyecto intenta hacer que un microcontrolador se haga pasar por una llave de seguridad U2F, para comunicarse con el microcontrolador por USB desde Firefox.
Con la JavaScript Credentials API(https://developer.mozilla.org/en-US/docs/Web/API/Credential_...) y algunos trucos, envía datos y recibe respuestas.
Aun así, puede usarse para crear dispositivos personalizados que una página web pueda usar sin un aviso de consentimiento.
Personalizar teclados con firmware QMK/Via mediante WebUSB es casi una pesadilla.
Para que el navegador se comunique con el firmware, en la práctica hay que hacer que un dispositivo
/dev/hidrawsea legible por todo el mundo, lo que invita a todo tipo de travesuras de keylogging.La forma de uso se siente muy turbia, y como todas las herramientas de personalización offline también están basadas en Electron, la ventaja no es tan grande.
La solución alternativa más razonable es crear la distribución de teclado deseada en un sitio web usando un JSON de plantilla, descargar el JSON resultante y luego grabar el firmware en el teclado con una herramienta de flasheo con permisos sudo.
Aun así, estaría bueno que hubiera una forma menos turbia.
main()en ejecución.Parece que los teclados podrían hacer algo similar.
Solo habría que hacer que el sistema de archivos arroje error si se escribe JSON inválido, y poner atributos de seguridad en el sistema de archivos emulado para que solo el administrador pueda escribir.
No hace falta sudo; basta con aprobar el aviso de permisos al descargar o copiar la nueva configuración a la unidad flash virtual.
Parece que al menos Caps Lock también puede configurarse desde JavaScript, así que en la práctica se convierte en un bus de comunicación de 1 bit de ancho.
Con herramientas normales del SO podrían ser hasta 3 bits.
El punto central del modelo de permisos es que la familia de navegadores media el acceso al hardware.
Por supuesto, para que el navegador haga eso, hay que darle acceso al hardware desde el principio.
Si no confías en el navegador como administrador de la capa de abstracción de hardware, es comprensible, pero ese es el modelo que Via espera.
No veo por qué sería más “turbio” que darle al navegador permisos de cámara, micrófono o lectura de almacenamiento.
Incluso en una Chromebook corporativa administrada y bloqueada puedo entrar a https://usevia.app y modificar un teclado QMK sin problemas, y por supuesto en este dispositivo no puedo tocar ningún nodo de
/dev.QMK es todo flasheo manual.
Aun así, me sorprendió lo fácil que es personalizar la distribución, las capas y la iluminación con código, en gran parte gracias al apoyo de la comunidad.
No es tan cómoda como Via, pero tiene un editor gráfico de keymaps, compila el firmware y es mucho menos pesada.
Tuve una buena experiencia con placas de Keeb.io.
Este hilo de comentarios es interesante porque mezcla a personas que usan WebUSB y hablan de lo bueno que es, con gente que no lo usa y no entiende por qué hace falta.
Personalmente, me pareció excelente.
La mayoría de las utilidades WebUSB que uso también están disponibles como apps instalables, pero las uso tan rara vez que la versión web es mucho más fácil que instalar la app, actualizarla y luego ejecutarla.
Que sea una app menos para instalar también es una ventaja.
Pensé que sería popular entre quienes están cansados de tener que instalar una app para cada cosa.
Por eso es un arma de doble filo.
La comodidad y la seguridad no se llevan bien.
Es útil y fácil, pero también es demasiado bueno para que aparezcan vulnerabilidades.
La expansión desmedida de la web tiene que parar.
El navegador no debería convertirse en un fregadero universal que contenga todo lo que quiera cualquiera en la industria tecnológica.
Instalar aplicaciones nativas tampoco es tan difícil.
Estrictamente no es USB sino HID, pero la idea es similar.
Me salgo un poco del tema, pero la mayor parte de este hilo parece tratar sobre WebUSB en general más que sobre el post original.
Claro que el hack del post original en sí está bastante genial.
Por un lado, WebUSB realmente hace falta, pero al mismo tiempo de verdad no quiero que WebUSB esté en manos de usuarios comunes.
En la práctica, los pop-ups de consentimiento no funcionaron, y la gente aprueba cualquier cosa sin darse cuenta.
Dicen “no presioné nada”, pero terminas quitando 50 notificaciones push de spam y borrando permisos push de una docena de sitios de “noticias”.
Sinceramente, me gusta hasta cierto punto el modelo de permisos al estilo Internet Explorer.
Era un esquema en el que, para activar ciertas funciones, había que marcar un sitio como “confiable”.
Era difícil de encontrar, tomaba algo de tiempo, era un poco confuso y mostraba un ícono grande de advertencia bastante intimidante en un pop-up modal con estilo del sistema.
Si para usar APIs peligrosas como WebUSB o WebBluetooth hubiera que pasar por el proceso de marcar un sitio como “confiable”, mucha menos gente las activaría por accidente.
La experiencia de usuario seguiría siendo mejor que instalar una app nativa y, además, se obtiene sandboxing, así que ese compromiso parece valer la pena.
El usuario mayor promedio no tiene idea de qué son las notificaciones web.
Con el tiempo activa por accidente notificaciones de sitios web sospechosos, y realmente cree en notificaciones de spam web que le llegan al teléfono como “HELLO YOUR PHONE HAS VIRUS DOWNLOAD "CLEANER APP" TO FIX BEFORE PHONE DIE”.
Algunas personas parecen tener un superpoder para arruinar las cosas.
Si no haces que algo sea literalmente imposible, inevitablemente encontrarán una forma de hacerlo por accidente.
Siguen guías para cambiar configuraciones que no entienden, ejecutan funciones que no entienden y conceden accesos que no entienden.
Pasa sin importar cuán complicado hagas el procedimiento, cuántas advertencias agregues o cuánto intentes impedir esa estupidez.
El problema es que también hay personas que saben lo que hacen y lo usan intencionalmente.
Esas personas pueden agradecer funciones potentes que jamás deberían darse a un tonto.
Pero lo doloroso es que, si expones ese poder, en la práctica es difícil evitar que se llene de gente haciendo estupideces.
Un gran problema es no entender correctamente que muchos usuarios no entienden en absoluto lo que están haciendo.
Google no entiende cómo diseñar software seguro para esas personas.
Los procedimientos molestos parecen inútiles, pero a menudo tienen un propósito claro:
comprobar que la intención del usuario sea firme.
Apple implementó recientemente algunas APIs web para que funcionen solo si el sitio web está instalado, y parece una estrategia que entiende el diseño para personas.
Permite acceder a funciones útiles de PWA, pero no deja que cualquier sitio las use arbitrariamente.
Hay un paso adicional que una persona común puede entender.
Una PWA instalada sigue visible en la pantalla de inicio, así que recuerda de forma visible el permiso concedido y es una señal clara de que el usuario quería ese acceso.
Mucha gente necesita interactuar con dispositivos, y hoy muchas veces la única opción práctica son apps distribuidas a través de App Stores cerradas.
Para distribuir a más personas una forma de acceder a dispositivos que ya dejaron de tener soporte oficial, WebUSB es, por mucho, el método más sencillo.
En otro mundo donde Chrome no lo soportara, el usuario común tendría que poder instalar y ejecutar [python or other scripting language].
Si el desarrollador fuera realmente dedicado, quizá tendría que ofrecer una app de escritorio o pasar por el proceso largo y caro de envío a la App Store.
Creo que se puede crear una UI segura para WebUSB, y tampoco se me ocurren muchos dispositivos que un usuario promedio tenga conectados y que puedan verse comprometidos.
Con WebUSB no se podría tomar control de teclados o mouse (HID), almacenamiento, Wi-Fi, audio, tarjetas inteligentes ni dispositivos U2F.
Pero es muy útil para impresoras de etiquetas propietarias, juguetes y aparatos varios, y para programar y flashear microcontroladores.
Son fáciles y cómodos de usar, pero también facilitan conceder por accidente un acceso muy amplio a terceros no confiables.
Dar permisos a una página debería ser, como dijiste, un flujo iniciado explícitamente por el usuario desde el panel de permisos.
Lo mismo aplica a las aplicaciones de escritorio en sandbox.
Si una app quiere grabar la pantalla continuamente, debería obtener ese permiso explícitamente desde el panel de control de permisos.
No debería poder mostrar un diálogo modal que lleve a la gente a simplemente presionar “yes”.
En muchos casos, la gente no entiende técnicamente qué se le está pidiendo.
USB Serial es realmente excelente
Por fin acaba con esas molestas apps de Electron que sirven para una sola cosa
Ahora hay herramientas para configurar dispositivos desde el navegador, y eso está muy bien
Basta ver ESPHome y los cientos de proyectos basados en él, Betaflight, ELRS y Flipper
Entiendo que WebKit tenga poco soporte porque lo desarrolla Apple, y también entiendo que serían cautelosos si permitieran acceso a periféricos
Pero Firefox es distinto
Firefox ha tenido una falta grave de soporte para “conectar” hardware y desde hace mucho no ha sido amigable con los desarrolladores, así que al final dejé de usarlo
Dicen que la razón para no dar soporte es que el consentimiento del usuario por sí solo no basta para acceder a dispositivos, pero eso no tiene sentido
Podrían haberlo puesto aunque fuera detrás de una flag para desarrolladores
Blink demostró que se puede hacer de forma segura
Parece que se obstinan sin motivo y no ven los casos de uso que harían que el navegador valiera la pena
https://developer.mozilla.org/en-US/docs/Web/API/Serial
https://mozilla.github.io/standards-positions/
Se supone que las credenciales U2F no deberían ser vulnerables al phishing
Es porque la API U2F del navegador incluye el nombre de dominio en la solicitud al token
Pero con WebUSB, un sitio podía pedir un token para un nombre de dominio arbitrario
Como U2F y WebUSB mostraban cuadros de consentimiento del usuario bastante parecidos, en la práctica era imposible evitar que algunos usuarios se confundieran
Cuesta creerlo, pero la solución de Google fue poner muchos dispositivos en una lista de bloqueo de WebUSB
Ahora, quienes fabrican dispositivos U2F tienen que pedirle a Google que los agregue a la lista de bloqueo cada vez que lanzan un producto nuevo
A todos les gusta que el navegador sea un sandbox seguro que permite ejecutar código no confiable, pero no entiendo por qué quieren hacerle tantos agujeros a ese sandbox
[1] https://www.yubico.com/support/security-advisories/ysa-2018-...
[2] https://github.com/WICG/webusb/blob/main/blocklist.txt
No creo que valga la pena asumir el riesgo de fingerprinting por unas decenas de usuarios finales que no quieren descargar una app de Electron para interactuar con hardware físico
Implementar una función y encerrarla detrás de un toggle para desarrolladores es una locura
Es desperdiciar cientos de horas de desarrollo que podrían usarse en algo útil, solo para exponer una función que de todos modos nadie va a encontrar
Como desarrollador, no me importa que estas API exclusivas de Chrome se queden solo en Chrome
De todos modos hay que tener un navegador Chromium a la mano por si algún sitio realmente se rompe en Firefox, así que puedo usarlo cuando tenga que trabajar con USB en la web
Es una demostración tecnológica interesante, pero no es algo que deba hacer el navegador
El hecho de que nadie haya agregado WebUSB mediante una extensión de Firefox también parece demostrar que, ni siquiera para quienes usan esta función, vale la pena invertir tiempo de desarrollo en ella
Se han planteado problemas de privacidad y seguridad
Web Serial no es un estándar web, y no puede convertirse en uno hasta que Mozilla o Apple consideren que esos problemas están resueltos
Google no puede convertirlo en estándar web por su cuenta; los estándares requieren consenso
La discusión de Mozilla está aquí: https://github.com/mozilla/standards-positions/issues/336
La discusión de WebKit está aquí: https://github.com/WebKit/standards-positions/issues/199
Me cuesta imaginar abandonar Firefox para navegar por la web por culpa de webusb
Tiene que ser software que se pueda descargar y que no dependa de servidores externos
Dicho eso, si el dispositivo ya depende desde el inicio de los servidores de esa empresa para funcionar, entonces está bien no tener que descargar software ni confiar en él
Que el código basado en navegador no pueda usar puertos USB quizá sea algo bueno
Porque ya no necesito abrir una VM con Windows para ejecutar actualizaciones de firmware o herramientas utilitarias de fabricantes de equipos de audio que lo soportan, por ejemplo Novation
WebUSB debería permitir lo mismo con más tipos de dispositivos, pero por supuesto tendría que haber un mecanismo de permisos adecuado
La ventaja es clara para quienes flashean dispositivos con frecuencia
Pero a los usuarios comunes, es decir, a los otros 3.000 millones de personas más o menos, no les importa en absoluto
Hacer agujeros en el sandbox por ellos es, en el mejor de los casos, imprudente
La solución podría ser una herramienta separada dedicada a este uso, quizá incluso un navegador separado
Algo como Flash Browser
Podría incluir herramientas adicionales para ayudar con esta tarea
Por ejemplo, listas de permitidos o de bloqueo preconfiguradas, marcadores a herramientas de flasheo comunes y material de referencia
Se podría crear una experiencia mejor que pegar WebUSB a la fuerza en el navegador tal cual
Entiendo la controversia y las críticas alrededor de ese “estándar”, pero cuando lo usé para flashear GrapheneOS en un teléfono Pixel, fue la instalación de un sistema operativo más cómoda, fácil y rápida que haya hecho en cualquier dispositivo
Literalmente fue conectar, hacer clic y empezar a usarlo
Me sorprende la parte de que cifran la clave privada con una clave “maestra” y devuelven la clave privada cifrada como identificador de clave
En la práctica sí debería funcionar
Darle a un atacante infinitas oportunidades para intentar descifrar la clave privada que tiene en la mano suena como algo que algún día podría salir mal, pero qué sé yo
Por ejemplo, otro enfoque podría ser generar la clave privada a partir de una derivación determinista desde el identificador de clave
Un atacante podría forzarla por fuerza bruta igual que la clave cifrada específica del sitio almacenada en el identificador de clave
El punto clave es que un autenticador sin estado, por definición, es determinista de forma global, es decir, entre el secreto y todos los sitios
Dado un par entrada-salida, se puede intentar recuperar el secreto interno por fuerza bruta
La solución es hacer que ese estado interno sea lo suficientemente grande como para que sea computacionalmente inviable
Me da curiosidad cuál es la controversia política alrededor de WebUSB
Es una API exclusiva de Blink creada por Google, y Mozilla y Apple la rechazaron por motivos de privacidad y seguridad
Sin dos implementaciones independientes no puede convertirse en un estándar web, y Google no logró convencer a nadie fuera de Google de implementarla
Aun así, en muchos sitios web aparece como si Firefox y Safari “no pudieran soportarla”
“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
El navegador ya puede acceder a los dispositivos USB que necesita mediante las interfaces normales del sistema operativo
El teclado y el mouse son ejemplos obvios
No veo qué sitio web tendría que necesitar acceso directo por separado
Los casos de uso parecen ser darles acceso a programadores web a los que les da flojera usar una aplicación independiente, o proporcionar una forma adicional de rastrear usuarios
No quiero confiar en ninguno de los dos
Ni siquiera confío en Google y Mozilla lo suficiente como para darles ese acceso, mucho menos a cualquier desconocido al azar que haya creado un sitio web
No todo tiene que ser accesible desde la web
No sé dónde debería trazarse la línea, pero para mí el acceso USB la cruza
Normalmente es una pelea que ganan quienes quieren la funcionalidad ahora mismo
Porque las fallas de seguridad parecen un problema hipotético hasta que se explotan en el mundo real
Cuantas más tenga, más profunda se vuelve la dependencia de Chrome
Yo tampoco quiero eso