DEV Community

Erick Takeshi
Erick Takeshi

Posted on • Edited on

1

OAuth em aplicações SPA / Mobile (PKCE extension)

Em diversas implementações OAuth / OpenID Connect nos deparamos com o uso de clientes confidenciais (clientes registrados que possuem um par client_id e client_secret), porém, em aplicações client-side, como SPAs e apps mobile, é impossível garantir a confidencialidade do client_secret. Portanto, torna-se necessário um meio seguro para obter o access token através de algum fluxo do OAuth.

Para resolver esse problema de clientes públicos, entra em ação a RFC 7636 Proof Key for Code Exchange by OAuth Public Clients, que adiciona uma extensão ao fluxo do authorization code, tornando a comunicação mais segura. É dessa RFC que quero aprofundar um pouco neste post.

Qual problema o PKCE tenta mitigar?

Primeiramente, lê-se piquici (pixy), a sigla PKCE, haha.

O PKCE mitiga um conhecido ataque do tipo man in the midle , aplicado principalmente em aplicações mobile, segue um diagrama abaixo demostrando esse tipo de ataque.

authz-code-attack-mitm

Explicando brevemente:

  1. A aplicação cliente inicia o fluxo authorization code utilizando um browser
  2. Browser faz o request para o endpoint /authorize do authorization server
  3. Browser recebe de volta a resposta do servidor com o authorization code (code)
  4. Um app malicioso instalado no dispositivo cliente intercepta essa resposta que seria encaminhada do browser para a aplicação cliente (normalmente utilizando um custom URI scheme)
  5. O app malicioso, em posse do authorization code , completa o fluxo trocando o code pelo access token e tendo acesso aos recursos protegidos autorizados pelo usuário.

Desta forma, um app malicioso que tenha infectado o dispositivo do cliente pode obter acesso a um access token interceptando code da resposta do request para o endpoint /authorize.

Um ponto importante a se destacar é que devido a natureza dos clientes públicos de não conseguirem guardar de maneira segura suas credenciais, o fluxo do authorization code permite que estes obtenham o access token somente através da posse do code e do cliente_id da aplicação cliente. Este tipo de ataque se tornaria bem menos eficaz caso fosse possível autenticar a aplicação cliente através de seu client_secret.

OBS sobre custom URI schemes

Para quem não é da área mobile ou front-end, custom URI schemes é uma forma de criar um protocolo custom para sua aplicação, assim como http:// ou https://, algo como myapp://.

Assim, quando um usuário clicar ou for redirecionado para uma URL que utilize este protocolo, sua aplicação será inicializada com os parâmetros associados a URL.

Para saber mais sobre indico este ótimo e breve artigo, Launching Applications from the Web: The Power of Custom URL Schemes.

Como o PKCE mitiga este tipo de ataque?

O PKCE mitiga este tipo de ataque introduzindo alguns parâmetros adicional nos requests envolvidos no fluxo do authorization code.

No diagrama abaixo ilustramos essa nova dinâmica:

pkce-athz-code-flow

Explicando o novo fluxo:

  1. Aplicação cliente cria um code_verifier, uma string aleatória de alta entropia criptográfica
  2. Aplicação cliente deriva o code_challenge do code_verifier aplicando algum algoritmo como SHA256, sendo este algoritmo denomiado code_challenge_method
  3. Aplicação cliente encaminha o code_challenge e o code_challenge_method , junto dos demais parâmetros, no request para o /authorize
  4. O authorization server guarda o code_challenge e o code_challenge_method, associando-os ao authorization code emitido na resposta do /authorize
  5. No request para o /token a aplicação cliente envia junto do code o code_verifier gerado no passo 1, além dos demais parâmetros necessários
  6. Authorization server vai aplicar as transformações no code_verifier baseado no code_challenge e code_challenge_method associados com o authorization code recebido
  7. Caso a verificação seja bem sucedida, o authorization server retorna o access code para a aplicação cliente

Então, com a introdução destes novos parâmetros, mesmo que algum app malicioso seja capaz de interceptar o authorization code, este não será capaz de trocar o code por um access token no endpoint /token por não saber o code_verifier e o code_challenge_method utilizado na comunicação com o authorization server.

Considerações de segurança

A extensão do PKCE parte do princípio que o code verifier pode ser mantido em segredo do atacante (app malicioso) e que é praticamente impossível de ser adivinhado ou derivado pelo atacante.

Para que o code verifier atinja o requisito satisfatório de aleatoriedade criptográfica, sugere-se utilizar pelo menos 256 bits de entropia.

Pessoalmente, sugiro que utilize bibliotecas open-source confiáveis para gerar o code_challege e verifier, uma vez que são padrões conhecidos. Recorrer a experiência e poder do open-source é sempre bem vindo.

Concluindo

O PKCE resolve o problema de clientes públicos, como SPAs e Mobile apps, em obter de maneira segura o access token, usufruindo assim dos benefícios do OAuth sem precisar comprometer sua segurança, então lembre-se sempre de utilizar essa extensão ao implementar clientes OAuth públicos.

Para saber mais sobre OAuth e OpenID Connect, deixo aqui a minha coletânea de posts sobre o tema.

Sentry mobile image

App store rankings love fast apps - mobile vitals can help you get there

Slow startup times, UI hangs, and frozen frames frustrate users—but they’re also fixable. Mobile Vitals help you measure and understand these performance issues so you can optimize your app’s speed and responsiveness. Learn how to use them to reduce friction and improve user experience.

Read full post →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay