Tokens OAuth, claves API y vídeos privados de YouTube se filtran carácter por carácter.

En Chrome descubrieron una forma de extraer la URL completa de cualquier pestaña abierta incluso de una extensión a la que formalmente no se le había concedido acceso ni a las pestañas ni a los sitios. Basta con que la extensión tenga únicamente el permiso declarativeNetRequest. Normalmente se considera relativamente seguro, porque está relacionado con reglas que bloquean solicitudes y no permite leer directamente el contenido de las páginas. Pero un investigador demostró que eso basta para averiguar la dirección de la página carácter por carácter, basándose en la diferencia de tiempo entre cargas bloqueadas y permitidas.
El elemento clave aquí es la API declarativeNetRequest. Permite a las extensiones añadir reglas dinámicas que bloquean solicitudes según un patrón. Esas reglas pueden hacer coincidir URL mediante expresiones regulares. En Chrome una solicitud bloqueada se interrumpe de inmediato y devuelve el error net::ERR_BLOCKED_BY_CLIENT, prácticamente al instante. Si la regla no coincide, el navegador continúa la carga habitual, que tarda notablemente más porque comienzan las conexiones de red. Ese tiempo es la pista que la extensión puede usar como "oráculo".
Dentro de Chromium el comportamiento de bloqueo es tal que, al coincidir una regla, el sistema limpia los callbacks pendientes y finaliza rápidamente el procesamiento con net::ERR_BLOCKED_BY_CLIENT. Para la extensión eso significa dos escenarios distintos. Cuando el bloqueo se activa, la respuesta es rápida; en la reproducción la diferencia fue de aproximadamente 10–30 ms. Si no hay coincidencia, la solicitud sigue y la latencia aumenta, del orden de 50–100 ms o más, según la red y el sitio.
Para medir este efecto, la extensión usa dos mecanismos habituales que no requieren el permiso tabs. Primero, invoca chrome.tabs.reload para iniciar la recarga de la página. Segundo, se suscribe a chrome.tabs.onUpdated y espera el evento en el que el estado cambia a complete. Después solo queda medir cuánto tiempo pasa entre reload y el momento en que la pestaña termina de cargarse. Rápido significa que la solicitud fue cortada por una regla. Lento significa que el navegador intentó realmente cargar la página.
A partir de ahí es pura matemática. La extensión crea una regla dinámica de bloqueo con una expresión regular que comprueba una posición concreta en la URL. La regla se diseña de modo que una coincidencia indique que el carácter en esa posición pertenece a un subconjunto determinado de valores posibles. Luego la extensión recarga la pestaña y, por el tiempo, determina si coincidió o no. Repitiendo la prueba y haciendo una búsqueda binaria sobre el conjunto de caracteres, se puede reconstruir la dirección carácter por carácter con un número pequeño de pasos por símbolo. El autor del informe adjuntó el video repro.mp4, donde la filtración se ve en la consola, los caracteres aparecen uno tras otro.
El peligro de esta técnica es que no requiere interacción del usuario y no deja señales evidentes. Una extensión puede recopilar silenciosamente datos sensibles de la barra de direcciones y luego enviarlos al exterior. Se citan como ejemplos códigos OAuth y tokens en URL como https://accounts.google.com/callback?code=secret, parámetros de identificadores de sesión y claves de API en la cadena de consulta, enlaces a materiales privados o "no indexados" incluyendo YouTube, Google Drive y Dropbox, tokens para restablecer contraseñas, así como consultas de búsqueda, incluso médicas o financieras. La filtración puede hacerse casi imperceptible, por ejemplo minimizando la ventana o enviándola al segundo plano mientras se extraen los caracteres.
El investigador intentó determinar cuándo apareció exactamente el problema. Un bisect inicial redujo el rango de regresión a las revisiones 718858–718878 en el repositorio Chromium. Un análisis adicional apunta al commit 1539dcc828ee3ba96c0949f1202cf9139b883d82, donde se añadió la evaluación de expresiones regulares a las reglas de declarativeNetRequest, lo que permitió que la demostración actual funcionara. El autor admite que un enfoque similar podría haberse adaptado a versiones anteriores, posiblemente hasta la aparición de la API Dynamic Rules en el cambio 1531023, es decir, mucho antes del commit indicado.
Las pruebas se llevaron a cabo en Windows 11 24H2. La vulnerabilidad se reproducía en varias ramas de Chrome. En la lista figuran Stable 144.0.7559.97, Beta 145.0.7632.18, Dev 146.0.7647.4 y Canary 146.0.7653.0.
El escenario de reproducción es sencillo. Hay que abrir una pestaña con una dirección del tipo https://accounts.google.com/callback?code=secret y situarla como primera. Luego cargar en el navegador una extensión de prueba formada por dos archivos, manifest.json y background.js. A continuación se abre DevTools para el service worker de la extensión, y en la consola se puede ver cómo la URL se extrae carácter por carácter.