A partir do sgcWebSockets 2024.5.0, o PKCE, que significa "Proof of Key Code Exchange", é uma extensão do protocolo OAuth 2.0 que ajuda a evitar ataques de interceptação de código.
O PKCE é suportado nos componentes OAuth2 Server e Client.
O que é o PKCE
O PKCE (Proof Key for Code Exchange) é um aprimoramento de segurança do OAuth 2.0 projetado para proteger contra ataques de interceptação de código de autorização em aplicações públicas ou nativas. Está detalhado na RFC 7636 e serve como técnica de mitigação contra a vulnerabilidade de "interceptação de código de autorização", particularmente em ambientes onde os client secrets não podem ser mantidos confidenciais de forma confiável, como em aplicações móveis ou do lado do cliente.
Em um fluxo típico Authorization Code Grant do OAuth 2.0, uma aplicação cliente obtém um código de autorização redirecionando o usuário para um servidor de autorização e, em seguida, troca o código por um access token. No entanto, se um invasor interceptar o código de autorização, ele poderia potencialmente usá-lo para obter o access token e acessar recursos protegidos.
O PKCE resolve esse risco introduzindo um mecanismo de proof key. Os principais componentes do PKCE são:
- Code Verifier: uma string aleatória de alta entropia gerada pela aplicação cliente no início do fluxo OAuth. O verifier deve ter no mínimo 43 caracteres e no máximo 128 caracteres, usando caracteres não reservados (A-Z, a-z, 0-9, "-", ".", "_", "~").
- Code Challenge: uma versão derivada do code verifier, criada usando um método de transformação. O método de transformação é geralmente "S256", indicando hashing SHA-256, mas também pode ser "plain", onde o code challenge é igual ao code verifier.
O fluxo PKCE funciona da seguinte forma:
- A aplicação cliente gera um code verifier e deriva o code challenge a partir dele.
- A aplicação cliente inicia a requisição de autorização OAuth, incluindo o code challenge e o método de code challenge (plain ou S256).
- O servidor de autorização envia o código de autorização para o cliente depois que o usuário concede acesso.
- Quando a aplicação cliente envia o código de autorização para o token endpoint para trocá-lo por um access token, ela também inclui o code verifier.
- O servidor de autorização verifica o code verifier aplicando o mesmo método de transformação usado para criar o code challenge e checa se ele corresponde ao code challenge armazenado.
- Se a verificação for bem-sucedida, o servidor de autorização emite o access token; caso contrário, a requisição é rejeitada.
Esse mecanismo garante que apenas o cliente com o code verifier original possa trocar com sucesso o código de autorização por um access token, fornecendo uma robusta camada de segurança nos fluxos OAuth.
Delphi OAuth2 Client
O componente TsgcHTTP_OAuth2_Client suporta o fluxo Authorization Code + PKCE. Para usar esse tipo de autorização, defina a propriedade GrantType com o valor auth2CodePKCE.
oAuth2 := TsgcHTTP2_OAuth2.Create(nil);
oAuth2.LocalServerOptions.Host := '127.0.0.1';
oAuth2.LocalServerOptions.Port := 8080;
oAuth2.AuthorizationServerOptions.AuthURL := 'https://accounts.google.com/o/oauth2/auth';
oAuth2.AuthorizationServerOptions.TokenURL := 'https://accounts.google.com/o/oauth2/token';
oAuth2.AuthorizationServerOptions.Scope.Add('https://mail.google.com/');
oAuth2.OAuth2Options.ClientId := '180803918357-eqjtn20gqfhcs6gjkebbrrenh022mqqc.apps.googleusercontent.com';
oAuth2.OAuth2Options.ClientSecret := '_by0iYYrvVHxC2Z8TbtNEYQN';
oAuth2.OAuth2Options.GrantType := auth2CodePKCE;
procedure OnOAuth2AfterAccessToken(Sender: TObject; const Access_Token, Token_Type, Expires_In,
Refresh_Token, Scope, RawParams: string; var Handled: Boolean);
begin
<...>
<...>
end;
oAuth2.OnAfterAccessToken := OnOAuth2AfterAccessToken;
oAuth2.Start;
Delphi OAuth2 Server
O componente TsgcHTTP_OAuth2_Server suporta PKCE por padrão (embora possa ser desabilitado na propriedade OAuth2Options.PKCE). Quando o servidor detecta que o cliente OAuth2 está usando PKCE, ele validará se os valores PKCE são válidos; caso contrário, a resposta retornará um erro.
Veja abaixo um link sobre como usar o Delphi OAuth2 Server.
