Oauthlib: Client_secret y code_verifier (PKCE) deben transmitirse de forma segura

Creado en 19 abr. 2019  ·  19Comentarios  ·  Fuente: oauthlib/oauthlib

client_secret y code_verifier se aceptan cuando se envían como parámetros en la cadena de consulta

Se debe verificar la presencia de Request.client_secret en los encabezados o el cuerpo y Request.code_verifier solo en el cuerpo, pero no en la cadena de consulta, ya que se trata de datos confidenciales.
Se pueden realizar comprobaciones adicionales, como el tipo de solicitud es POST y los datos se enviaron usando HTTPS .

Cuando se envía client_secret o code_verifier en una cadena de consulta, debería dar como resultado una solicitud incorrecta, lo que obliga al cliente a enviar datos de forma segura.

Bug Contributor Friendly OAuth2-Provider

Comentario más útil

Hola @polamayster , tienes toda la razón.

Estoy agregando las secciones de RFC que especifican cómo debe implementarse:

Sección 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.

Sección 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:

De modo que no tengo ninguna duda sobre la pertinencia del tema. ¡Cualquier RP es bienvenido!

Todos 19 comentarios

Hola @polamayster , tienes toda la razón.

Estoy agregando las secciones de RFC que especifican cómo debe implementarse:

Sección 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.

Sección 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:

De modo que no tengo ninguna duda sobre la pertinencia del tema. ¡Cualquier RP es bienvenido!

Estoy interesado en asumir esto. Pronto enviará una solicitud de extracción.

¿Debería aplicarse este comportamiento solo para las solicitudes que esperan credenciales o cualquier solicitud en general?

A mi entender oauthlib.common.Request clase tiene un __getattr__ método y _params diccionario (actualizado de cadena de consulta y parámetros corporales) y cualquier solicitud que intenta acceder a / get client_secret o code_verifier deben buscar solo en el cuerpo y / o encabezados (quizás tenga sentido tener una propiedad separada para la búsqueda de datos confidenciales)

Ya veo, enviaré un PR hoy

El sábado 20 de abril de 2019 a las 12:38 p.m., Bohdan < [email protected] escribió:

A mi entender, la clase oauthlib.common.Request tiene un __getattr__
método y diccionario _params (actualizado a partir de la cadena de consulta y el cuerpo
parámetros) y cualquier solicitud que intente acceder / obtener client_secret o
code_verifier solo debe buscar en el cuerpo y / o encabezados (tal vez teniendo
propiedad separada para la búsqueda de datos confidenciales tendría sentido)

-
Estás recibiendo esto porque hiciste un comentario.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/oauthlib/oauthlib/issues/666#issuecomment-485157051 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/ABKEVQNFJUFGDB5X24JBOJDPRNWKBANCNFSM4HHD7NNQ
.

A mi entender oauthlib.common.Request clase tiene un __getattr__ método y _params diccionario (actualizado de cadena de consulta y parámetros corporales) y cualquier solicitud que intenta acceder a / get client_secret o code_verifier deben buscar solo en el cuerpo y / o encabezados (quizás tenga sentido tener una propiedad separada para la búsqueda de datos confidenciales)

Entonces, ¿las comprobaciones deberían realizarse en el momento del acceso a los atributos en lugar de cuando se establece la URL? Si los atributos de la solicitud se establecen solo una vez en la inicialización, podemos realizar las comprobaciones en ese momento en lugar de en cada acceso a los atributos. Avíseme si cree que aún deberíamos realizar las comprobaciones en cada acceso de atributo.

Me doy cuenta de que este problema es mayor y se aplica a todo el punto final /token . Este punto final NO DEBE aceptar ningún parámetro en la URL. Eso NO DEBE estar permitido.

Creo que el punto final de la introspección también califica. IIRC, según
Especificaciones HTTP, las solicitudes POST siempre deben ignorar los parámetros de consulta. Si
Hacemos cumplir eso, automáticamente resolvemos todos los problemas sin afectar
casos de uso válidos. No estoy seguro de cómo se supone que se comportan otros verbos HTTP
pero estoy bastante seguro en la POST uno. ¿Alguien puede confirmar si eso es lo correcto?
dirección a la que ir?

>

¡Negar todos los parámetros de consulta para todos los POST es un buen atajo que es atractivo! Sin embargo, me preocupa el ResourceEndpoint de oauthlib y el hecho de que algunos de los usuarios aún pueden agregar argumentos de consulta a la URL (a pesar de que no se recomienda, todavía es posible técnicamente).

¿Puede explicar un poco más sus inquietudes con el punto final de recursos?

A mi modo de ver, las solicitudes POST se realizan a través de envíos de formularios o api
llamadas (escribir código explícito). No veo porque alguien agregaria parcial
datos como parámetros de consulta y parciales como datos de publicación. De hecho, es más fácil
comprometerse completamente con cualquiera.
En realidad, si está utilizando una biblioteca para realizar solicitudes, es mucho más fácil
agregue todo como cuerpo de la publicación en lugar de dividir las cosas.

Los usuarios que agregan parámetros de consulta a POST si se les presenta un error explicativo,
debe poder autocorregirse rápidamente.

O tal vez podamos crear un mixin o decorador que, cuando se aplique, aumente
errores para solicitudes POST con parámetros de consulta.

Aquí hay otra posible solución. Para los puntos finales ( AuthorizationEndpoint , IntrospectEndpoint , RevocationEndpoint ); Si el método de solicitud es POST , podemos agregar la verificación de los parámetros de consulta en sus respectivos métodos de validación de solicitudes. Para ( TokenEndpoint , MetadataEndpoint ) podemos agregar la verificación en los métodos de generación de respuestas.
O podemos agregar el mecanismo de verificación dentro del método de generación de respuesta de todos ellos, en aras de la coherencia. ¿Suena como una buena idea?

Creo que es preferible utilizar los métodos de validación _request_.
Sabiendo que POST es solo para TokenEndpoint , IntrospectEndpoint y RevocationEndpoint . Otros son GET : AuthorizationEndpoint , MetadataEndpoint .

Sin embargo, un comentario general: ¿deberíamos centrarnos en campos sensibles (por ejemplo, mantener una lista negra) o deberíamos denegar todos los parámetros de OAuth2 (queremos que NINGUNO esté en el URI de consulta, verdad?)

Idealmente, me gustaría NINGUNO en Query URI. Fui a una lista negra porque no estaba
seguro si podría estar rompiendo algunos casos de uso existentes. No solo no hay OAuth2
Se permiten parámetros, pero no se permiten parámetros de consulta.

>

Si mueve las comprobaciones de Solicitud a los puntos finales, no veo ningún problema al deshabilitar todos los parámetros de consulta para esos puntos finales.

Muy bien, inhabilitaré todos los parámetros de consulta en esos extremos exactos. Y
también estamos restringiendo el método http a POST, ¿correcto?

Si bien entiendo el razonamiento de este cambio, este parece ser un cambio importante para los clientes que envían client_secret como parámetro de consulta. Hubiera esperado compatibilidad con versiones anteriores o un aumento de la versión principal. ¿Este comportamiento es intencionado?

Actualmente estamos usando django-oauth-toolkit y los clientes están enviando username , password , client_secret , client_id y grant_type como consulta parámetro. Si cambian a enviar todo como parámetro POST , obtienen el error unsupported_grant_type .

El soporte de consultas para POST es más un efecto secundario que el comportamiento deseado. Entiendo que rompa a su cliente, por lo que sugiero señalar a <3.1
Además, considere actualizar lo antes posible, ya que implica problemas de seguridad (los secretos se muestran en registros, en proxy, en múltiples ubicaciones no deseadas).

¿Fue útil esta página
0 / 5 - 0 calificaciones