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.
Explicando brevemente:
- A aplicação cliente inicia o fluxo
authorization code
utilizando um browser - Browser faz o request para o endpoint /authorize do authorization server
- Browser recebe de volta a resposta do servidor com o
authorization code
(code) - 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)
- 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:
Explicando o novo fluxo:
- Aplicação cliente cria um
code_verifier
, uma string aleatória de alta entropia criptográfica - Aplicação cliente deriva o
code_challenge
do code_verifier aplicando algum algoritmo como SHA256, sendo este algoritmo denomiadocode_challenge_method
- Aplicação cliente encaminha o
code_challenge
e ocode_challenge_method
, junto dos demais parâmetros, no request para o /authorize - O authorization server guarda o code_challenge e o code_challenge_method, associando-os ao authorization code emitido na resposta do /authorize
- 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 - Authorization server vai aplicar as transformações no code_verifier baseado no code_challenge e code_challenge_method associados com o authorization code recebido
- 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.
Top comments (0)