Oauthlib: Client_secret 和 code_verifier (PKCE) 应该安全传输

创建于 2019-04-19  ·  19评论  ·  资料来源: oauthlib/oauthlib

client_secretcode_verifier在作为查询字符串中的参数发送时被接受

应检查Request.client_secret是否存在于标题或正文中, Request.code_verifier仅存在于正文中,但不检查查询字符串,因为它是敏感数据。
可能会进行附加检查,例如请求类型为POST并且数据是使用HTTPS

client_secretcode_verifier在查询字符串中发送时,它应该导致错误请求,强制客户端安全地发送数据。

Bug Contributor Friendly OAuth2-Provider

最有用的评论

@polamayster ,你说得对。

我正在添加 RFC 的部分,指定它必须如何实现:

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.

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:

所以我不怀疑这个问题的相关性。 欢迎任何 PR!

所有19条评论

@polamayster ,你说得对。

我正在添加 RFC 的部分,指定它必须如何实现:

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.

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:

所以我不怀疑这个问题的相关性。 欢迎任何 PR!

我有兴趣接受这个。 将很快提交拉取请求。

是否应该仅对需要凭据的请求或任何一般请求强制执行此行为?

据我了解oauthlib.common.Request类有一个__getattr__方法和_params字典(从查询字符串和正文参数更新)以及任何试图访问/获取client_secret请求client_secretcode_verifier应该只在正文和/或标题中查找(也许为敏感数据查找设置单独的属性是有意义的)

明白了,我今天就提交pr

2019 年 4 月 20 日星期六下午 12:38 Bohdan < [email protected]写道:

据我了解 oauthlib.common.Request 类有一个 __getattr__
方法和 _params 字典(从查询字符串和正文更新
参数)以及任何尝试访问/获取 client_secret 或的
code_verifier 应该只在正文和/或标题中查找(也许有
敏感数据查找的单独属性是有意义的)


您收到此消息是因为您发表了评论。
直接回复本邮件,在GitHub上查看
https://github.com/oauthlib/oauthlib/issues/666#issuecomment-485157051
或静音线程
https://github.com/notifications/unsubscribe-auth/ABKEVQNFJUFGDB5X24JBOJDPRNWKBANNCNFSM4HHD7NNQ
.

据我了解oauthlib.common.Request类有一个__getattr__方法和_params字典(从查询字符串和正文参数更新)以及任何试图访问/获取client_secret请求client_secretcode_verifier应该只在正文和/或标题中查找(也许为敏感数据查找设置单独的属性是有意义的)

所以检查应该在属性访问时而不是在设置 url 时进行? 如果请求属性在初始化时只设置一次,我们可以立即执行检查,而不是在每次访问属性时执行。 如果您认为我们仍然应该在每个属性访问中执行检查,请告诉我。

我意识到这个问题更大,适用于整个/token端点。 此端点不得接受 URL 中的任何参数。 这是绝对不允许的。

我认为内省端点也符合条件。 IIRC,根据
HTTP 规范,POST 请求必须始终忽略查询参数。 如果
我们强制执行,我们会自动解决所有问题而不会影响
有效的用例。 我不确定其他 HTTP 动词应该如何表现
但我很确定在 POST 一。 任何人都可以确认这是否正确
走向何方?

>

拒绝所有 POST 的所有查询参数是一个很好的捷径,很有吸引力! 但是,我担心 oauthlib 的 ResourceEndpoint 以及某些用户仍然可以向 URL 添加查询参数的事实(尽管不推荐这样做,但技术上仍然可行)。

您能否详细说明您对资源端点的担忧?

在我看来,POST 请求是通过表单提交或 api 发出的
调用(编写显式代码)。 我不明白为什么有人会添加部分
数据作为查询参数,部分作为发布数据。 其实更容易
完全承诺。
实际上,如果您使用库来发出请求,则要容易得多
将所有内容添加为帖子正文而不是拆分内容。

如果出现解释性错误,用户将查询参数添加到 POST,
应该能够快速自我纠正。

或者我们可以创建一个混合或装饰器,当应用时,会引发
带有查询参数的 POST 请求错误。

这是另一个可能的解决方案。 对于端点( AuthorizationEndpointIntrospectEndpointRevocationEndpoint ); 如果请求方法是POST我们可以在它们各自的请求验证方法中添加查询参数的检查。 对于 ( TokenEndpoint , MetadataEndpoint ) 我们可以在响应生成方法中添加检查。
或者,为了一致性,我们可以在所有响应生成方法中添加检查机制。 这听起来是个好主意吗?

我认为最好使用 _request_ 验证方法。
知道POST仅适用于TokenEndpointIntrospectEndpointRevocationEndpoint 。 其他的是GETAuthorizationEndpointMetadataEndpoint

不过一般评论:我们应该关注敏感字段(例如维护黑名单)还是应该拒绝所有 OAuth2 参数(我们希望 NONE 不在查询 URI 中,对吗?)

理想情况下,我希望查询 URI 中没有。 我去了黑名单,因为我不是
确定我是否可能会破坏一些现有的用例。 不仅没有 OAuth2
允许使用参数,但根本不允许使用查询参数。

>

如果您将检查从 Request 移到 Endpoints,我认为禁用这些 Endpoints 的所有查询参数没有任何问题!

那么,我将禁用那些确切端点上的所有查询参数。 和
我们也将 http 方法限制为 POST,对吗?

虽然我理解此更改的原因,但对于将client_secret作为查询参数发送的客户端来说,这似乎是一个重大更改。 我会期望向后兼容性或主要版本的提升。 这种行为是有意的吗?

我们目前正在使用 django-oauth-toolkit 并且客户端正在发送usernamepasswordclient_secretclient_idgrant_type作为查询范围。 如果他们切换到将所有内容作为POST参数发送,则会收到错误unsupported_grant_type

对 POST 查询的支持与其说是期望的行为,不如说是一种副作用。 我知道这会破坏您的客户,因此我建议您确定 <3.1
此外,请考虑尽快升级,因为它涉及安全问题(秘密显示在日志、代理、跨多个非预期位置)。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

JonathanHuot picture JonathanHuot  ·  33评论

ryarnyah picture ryarnyah  ·  3评论

jcampbell05 picture jcampbell05  ·  14评论

JonathanHuot picture JonathanHuot  ·  26评论

thedrow picture thedrow  ·  31评论