Oauthlib: Client_secret e code_verifier (PKCE) devem ser transmitidos com segurança

Criado em 19 abr. 2019  ·  19Comentários  ·  Fonte: oauthlib/oauthlib

client_secret e code_verifier são aceitos quando enviados como parâmetros na string de consulta

Request.client_secret deve ser verificado quanto à presença nos cabeçalhos ou corpo e Request.code_verifier apenas no corpo, mas não na string de consulta, pois são dados confidenciais.
Verificações de adição podem ser feitas, como o tipo de solicitação POST e os dados foram enviados usando HTTPS .

Quando client_secret ou code_verifier é enviado na string de consulta, isso deve resultar em Solicitação inválida, obrigando o cliente a enviar dados com segurança.

Bug Contributor Friendly OAuth2-Provider

Comentários muito úteis

Olá @polamayster , você está perfeitamente certo.

Estou adicionando as seções do RFC especificando como deve ser implementado:

Seção de OAuth2.0 RFC:

https://tools.ietf.org/html/rfc6749#section -2.3.1

2.3.1.  Client Password
   Clients in possession of a client password
   MAY use the HTTP Basic authentication scheme (..) 

   Alternatively, the authorization server
   MAY support including the client credentials in the request-body (..)

   The parameters can only be transmitted in the request-body and
   MUST NOT be included in the request URI.

Seção de PKCE RFC:

https://tools.ietf.org/html/rfc7636#section -4.5

4.5.  Client Sends the Authorization Code and the Code Verifier to the
      Token Endpoint
    In addition to the parameters defined in the OAuth 2.0 Access
    Token Request (Section 4.1.3 of [RFC6749]), it sends the following parameter:

   code_verifier
      REQUIRED.  Code verifier

https://tools.ietf.org/html/rfc6749#section -4.1.3


4.1.3.  Access Token Request

   The client makes a request to the token endpoint by sending the
   following parameters (..) in the HTTP request entity-body:

Portanto, não tenho dúvidas sobre a pertinência do assunto. Quaisquer PRs são bem-vindos!

Todos 19 comentários

Olá @polamayster , você está perfeitamente certo.

Estou adicionando as seções do RFC especificando como deve ser implementado:

Seção de OAuth2.0 RFC:

https://tools.ietf.org/html/rfc6749#section -2.3.1

2.3.1.  Client Password
   Clients in possession of a client password
   MAY use the HTTP Basic authentication scheme (..) 

   Alternatively, the authorization server
   MAY support including the client credentials in the request-body (..)

   The parameters can only be transmitted in the request-body and
   MUST NOT be included in the request URI.

Seção de PKCE RFC:

https://tools.ietf.org/html/rfc7636#section -4.5

4.5.  Client Sends the Authorization Code and the Code Verifier to the
      Token Endpoint
    In addition to the parameters defined in the OAuth 2.0 Access
    Token Request (Section 4.1.3 of [RFC6749]), it sends the following parameter:

   code_verifier
      REQUIRED.  Code verifier

https://tools.ietf.org/html/rfc6749#section -4.1.3


4.1.3.  Access Token Request

   The client makes a request to the token endpoint by sending the
   following parameters (..) in the HTTP request entity-body:

Portanto, não tenho dúvidas sobre a pertinência do assunto. Quaisquer PRs são bem-vindos!

Estou interessado em fazer isso. Enviaremos uma solicitação pull em breve.

Esse comportamento deve ser aplicado apenas para solicitações que esperam credenciais ou qualquer solicitação em geral?

Para o meu entendimento oauthlib.common.Request classe tem um __getattr__ método e _params dicionário (atualizado a partir de string de consulta e parâmetros do corpo) e qualquer pedido que tenta acessar / get client_secret ou code_verifier deve pesquisar apenas no corpo e / ou cabeçalhos (talvez faça sentido ter uma propriedade separada para a pesquisa de dados confidenciais)

Entendo, vou enviar uma proposta para isso hoje

No sábado, 20 de abril de 2019, 12h38, Bohdan < notificaçõ[email protected] escreveu:

No meu entendimento, a classe oauthlib.common.Request tem um __getattr__
método e dicionário _params (atualizado da string de consulta e corpo
parâmetros) e qualquer solicitação que tente acessar / obter client_secret ou
code_verifier deve apenas pesquisar no corpo e / ou cabeçalhos (talvez tendo
propriedade separada para pesquisa de dados confidenciais faria sentido)

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/oauthlib/oauthlib/issues/666#issuecomment-485157051 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/ABKEVQNFJUFGDB5X24JBOJDPRNWKBANCNFSM4HHD7NNQ
.

Para o meu entendimento oauthlib.common.Request classe tem um __getattr__ método e _params dicionário (atualizado a partir de string de consulta e parâmetros do corpo) e qualquer pedido que tenta acessar / get client_secret ou code_verifier deve pesquisar apenas no corpo e / ou cabeçalhos (talvez faça sentido ter uma propriedade separada para a pesquisa de dados confidenciais)

Portanto, as verificações devem acontecer no momento do acesso ao atributo, em vez de quando o url é definido? Se os atributos de solicitação forem definidos apenas uma vez na inicialização, podemos realizar as verificações imediatamente, em vez de em cada acesso ao atributo. Deixe-me saber se você acha que ainda devemos realizar as verificações em cada acesso de atributo.

Sei que esse problema é maior e se aplica a todo o endpoint /token . Este endpoint NÃO DEVE aceitar nenhum parâmetro no URL. Isso NÃO DEVE ser permitido.

Acho que o ponto final de introspecção também se qualifica. IIRC, de acordo com
Especificações HTTP, as solicitações POST devem sempre ignorar os parâmetros de consulta. Se
aplicamos isso, resolvemos automaticamente todos os problemas sem afetar
casos de uso válidos. Não tenho certeza de como outros verbos HTTP devem se comportar
mas tenho certeza do POST um. Alguém pode confirmar se isso é certo
direção a seguir?

>

Negar todos os parâmetros de consulta para todos os POST é um bom atalho que é atraente! No entanto, estou preocupado com o ResourceEndpoint do oauthlib e o fato de que alguns dos usuários ainda podem adicionar argumentos de consulta à URL (apesar de não ser recomendado, ainda é possível tecnicamente).

Você pode elaborar um pouco mais sobre suas preocupações com o endpoint de recursos?

A meu ver, as solicitações POST são feitas por meio de envios de formulários ou API
chamadas (escrever código explícito). Não vejo por que alguém adicionaria parcial
dados como parâmetros de consulta e parciais como dados de postagem. Na verdade, é mais fácil
comprometa-se completamente com qualquer um deles.
Na verdade, se você estiver usando uma biblioteca para fazer solicitações, é muito mais fácil
adicione tudo como post body em vez de dividir as coisas.

Os usuários adicionam parâmetros de consulta ao POST se houver um erro explicativo
deve ser capaz de se auto-corrigir rapidamente.

Ou talvez possamos criar um mixin ou decorador que, quando aplicado, aumentaria
erros para solicitações POST com parâmetros de consulta.

Aqui está outra solução possível para isso. Para os pontos de extremidade ( AuthorizationEndpoint , IntrospectEndpoint , RevocationEndpoint ); Se o método de solicitação for POST , podemos adicionar a verificação de parâmetros de consulta em seus respectivos métodos de validação de solicitação. Para ( TokenEndpoint , MetadataEndpoint ), podemos adicionar os métodos de geração de verificação na resposta.
OU podemos adicionar o mecanismo de verificação dentro do método de geração de resposta de todos eles, por uma questão de consistência. Isso te parece uma boa ideia?

Acho que é preferível usar os métodos de validação _request_.
Sabendo que POST é apenas para TokenEndpoint , IntrospectEndpoint e RevocationEndpoint . Outros são GET : AuthorizationEndpoint , MetadataEndpoint .

No entanto, um comentário geral: devemos nos concentrar em campos confidenciais (por exemplo, manter uma lista negra) ou devemos negar todos os parâmetros OAuth2 (queremos que NENHUM esteja no URI de consulta, certo?)

Idealmente, eu gostaria de NONE no URI de consulta. Eu fui para uma lista negra porque eu não era
certeza se posso estar quebrando alguns casos de uso existentes Não são apenas OAuth2
parâmetros permitidos, mas nenhum parâmetro de consulta é permitido.

>

Se você mover as verificações de Solicitação para os Endpoints, não vejo problemas na desativação de todos os parâmetros de consulta para esses Endpoints!

Tudo bem então, vou desabilitar todos os parâmetros de consulta nesses endpoints exatos. E
também estamos restringindo o método http para POST, correto?

Embora eu entenda o motivo dessa alteração, parece ser uma alteração importante para clientes que enviam client_secret como um parâmetro de consulta. Eu esperava compatibilidade com versões anteriores ou um solavanco de versão principal. Este comportamento é intencional?

No momento, estamos usando o django-oauth-toolkit e os clientes estão enviando username , password , client_secret , client_id e grant_type como consulta parâmetro. Se eles mudarem para o envio de tudo como parâmetro POST , eles obterão o erro unsupported_grant_type .

O suporte de consulta para POST é mais um efeito colateral do que o comportamento desejado. Eu entendo que quebrou seu cliente, então sugiro apontar para <3.1
Além disso, considere atualizar o mais rápido possível, pois isso envolve questões de segurança (os segredos são mostrados nos logs, no proxy, em vários locais indesejados).

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

JonathanHuot picture JonathanHuot  ·  26Comentários

ViktorHaag picture ViktorHaag  ·  11Comentários

ryarnyah picture ryarnyah  ·  3Comentários

thedrow picture thedrow  ·  31Comentários

prudnikov picture prudnikov  ·  11Comentários