为什么 webhook 实现避免基于令牌的安全性?
Why do webhook implementations avoid token based security?
在研究了各种 webhook 实现之后,我注意到了它们使用的安全机制的趋势。
Visual Studio Team Services webhooks 使用基本身份验证。
Microsoft Graph webhooks 在每个 webhook 调用的 body 中发送明文 "clientState"。接收方根据已知值验证 clientState。这类似于基本身份验证,因为每个请求都会通过网络发送明文凭据。
Slack 传出 webhook 使用与 Microsoft Graph 非常相似的技术:在每个请求的 body 中发送明文 "token"。接收方根据已知值验证令牌。同样,与基本身份验证非常相似:明文凭据随每个请求通过网络发送。
在上述所有示例中,凭据永不过期。此外,每个挂钩只有一个 "token" 值,这意味着如果令牌遭到破坏,则无法正常轮换令牌。
我对 Basic Auth 的理解是,通常会避免使用它,因为它要求客户端以明文形式存储凭据,这存在安全风险。
继续,Github and Box webhooks 使用共享密钥和签名进行身份验证。
用于 webhook 的安全机制与其各自使用的安全机制形成对比 API - 它们都使用 OAuth 2.0 和 JWT 承载令牌。
我还没有看到使用基于令牌的身份验证的 webhook 实现 - 例如,在授权中发送 JWT 不记名令牌的平台 header。
我的问题是:webhook 实现倾向于使用不太安全的机制(如基本身份验证)的原因是什么?为什么他们不像他们自己的 API 那样只使用 OAuth 2.0 和 JWT?
基于令牌的身份验证系统并不意味着 JWT 作为令牌格式。
如果您选择 Slack 或 MS Graph 实现并将 clientState
/token
从请求的 body 移动到 Authorization
header使用 Bearer
方案,您不会发现显着差异。 的确,header 是传递旨在验证请求的信息的最合适方式,服务器可能会以比请求 body 更安全的方式对待 header ]...但是为了便于讨论,让我们忽略它。
令牌将是一个 by-reference token,其中实际值没有意义,有效性和任何相关信息由消费者从独立商店获得。在这种情况下,纯粹通过确保令牌与您期望的值匹配来判断有效性,并且没有存储与令牌关联的其他信息,但这仍然是一个基于持有者令牌的身份验证系统,因为任何拥有令牌的人都可以提出要求。此外,令牌不是通过任何 OAuth 2.0 流程获得的,但对于像这样的场景来说,这就太过分了。
Github 实施将被归类为对纯承载实施的改进,因为在线路上没有令牌传输,只有有效负载的签名,这意味着攻击者能够解密通信通道将只能重放捕获的请求,而不能发出具有不同负载的请求。
结论
您可能找不到使用功能齐全的 OAuth 2.0 和 JWT 作为令牌格式的 webhooks 实现,因为这对于手头的用例来说太过分了。
更新:
JWT 的到期时间是您想要的任何时间,因为它将是 by-reference 令牌(您称之为简单令牌)的到期时间。
我试图传递的信息是,您不需要 JWT 或 OAuth 就可以拥有基于令牌的身份验证系统。基于令牌的系统的安全特性可以独立于所使用的令牌格式进行设计;是的,某些格式会简化某些方面,同时可能使其他方面更加复杂。它总是 trade-off...
在一个您只想确保来电者是您信任的人而不是完全陌生的系统中,JWT 似乎有点过分了;这当然是我的意见。
关于简单令牌本身是秘密取决于您所说的秘密的确切含义。不记名身份验证方案中使用的 JWT 或 by-reference 令牌在泄漏时会为您提供完全相同的结果。谁拥有令牌,谁就可以在令牌有效时发出请求。如果您指的是用于签署 JWT 的 secret/key,它不会在线上传输,那么如果您使用已签名的 by-reference 令牌,这又是完全相同的。
同样,对您的基本问题的诚实回答是,考虑到系统的威胁模型,这些系统添加了他们认为值得的安全机制。就个人而言,我并不反对不使用 OAuth 2.0 和 JWT,因为在那个用例中它似乎完全不值得。我的偏好是采用 Github 方法。
您可能不喜欢它们提供的安全特性,但 MS Graph 和 Slack 方法都是使用不记名令牌的基于令牌的系统。
在研究了各种 webhook 实现之后,我注意到了它们使用的安全机制的趋势。
Visual Studio Team Services webhooks 使用基本身份验证。
Microsoft Graph webhooks 在每个 webhook 调用的 body 中发送明文 "clientState"。接收方根据已知值验证 clientState。这类似于基本身份验证,因为每个请求都会通过网络发送明文凭据。
Slack 传出 webhook 使用与 Microsoft Graph 非常相似的技术:在每个请求的 body 中发送明文 "token"。接收方根据已知值验证令牌。同样,与基本身份验证非常相似:明文凭据随每个请求通过网络发送。
在上述所有示例中,凭据永不过期。此外,每个挂钩只有一个 "token" 值,这意味着如果令牌遭到破坏,则无法正常轮换令牌。
我对 Basic Auth 的理解是,通常会避免使用它,因为它要求客户端以明文形式存储凭据,这存在安全风险。
继续,Github and Box webhooks 使用共享密钥和签名进行身份验证。
用于 webhook 的安全机制与其各自使用的安全机制形成对比 API - 它们都使用 OAuth 2.0 和 JWT 承载令牌。
我还没有看到使用基于令牌的身份验证的 webhook 实现 - 例如,在授权中发送 JWT 不记名令牌的平台 header。
我的问题是:webhook 实现倾向于使用不太安全的机制(如基本身份验证)的原因是什么?为什么他们不像他们自己的 API 那样只使用 OAuth 2.0 和 JWT?
基于令牌的身份验证系统并不意味着 JWT 作为令牌格式。
如果您选择 Slack 或 MS Graph 实现并将 clientState
/token
从请求的 body 移动到 Authorization
header使用 Bearer
方案,您不会发现显着差异。 的确,header 是传递旨在验证请求的信息的最合适方式,服务器可能会以比请求 body 更安全的方式对待 header ]...但是为了便于讨论,让我们忽略它。
令牌将是一个 by-reference token,其中实际值没有意义,有效性和任何相关信息由消费者从独立商店获得。在这种情况下,纯粹通过确保令牌与您期望的值匹配来判断有效性,并且没有存储与令牌关联的其他信息,但这仍然是一个基于持有者令牌的身份验证系统,因为任何拥有令牌的人都可以提出要求。此外,令牌不是通过任何 OAuth 2.0 流程获得的,但对于像这样的场景来说,这就太过分了。
Github 实施将被归类为对纯承载实施的改进,因为在线路上没有令牌传输,只有有效负载的签名,这意味着攻击者能够解密通信通道将只能重放捕获的请求,而不能发出具有不同负载的请求。
结论
您可能找不到使用功能齐全的 OAuth 2.0 和 JWT 作为令牌格式的 webhooks 实现,因为这对于手头的用例来说太过分了。
更新:
JWT 的到期时间是您想要的任何时间,因为它将是 by-reference 令牌(您称之为简单令牌)的到期时间。
我试图传递的信息是,您不需要 JWT 或 OAuth 就可以拥有基于令牌的身份验证系统。基于令牌的系统的安全特性可以独立于所使用的令牌格式进行设计;是的,某些格式会简化某些方面,同时可能使其他方面更加复杂。它总是 trade-off...
在一个您只想确保来电者是您信任的人而不是完全陌生的系统中,JWT 似乎有点过分了;这当然是我的意见。
关于简单令牌本身是秘密取决于您所说的秘密的确切含义。不记名身份验证方案中使用的 JWT 或 by-reference 令牌在泄漏时会为您提供完全相同的结果。谁拥有令牌,谁就可以在令牌有效时发出请求。如果您指的是用于签署 JWT 的 secret/key,它不会在线上传输,那么如果您使用已签名的 by-reference 令牌,这又是完全相同的。
同样,对您的基本问题的诚实回答是,考虑到系统的威胁模型,这些系统添加了他们认为值得的安全机制。就个人而言,我并不反对不使用 OAuth 2.0 和 JWT,因为在那个用例中它似乎完全不值得。我的偏好是采用 Github 方法。
您可能不喜欢它们提供的安全特性,但 MS Graph 和 Slack 方法都是使用不记名令牌的基于令牌的系统。