Django Rest Framework 和 OAuth2 Toolkit 的额外保护层

Extra protection layer for Django Rest Framework and OAuth2 Toolkit

这是 的跟进问题。

我使用的是最新的 Django OAuth2 Toolkit (0.10.0) Python 2.7、Django 1.8 和 Django REST framework 3.3

一些背景:
进行身份验证时,客户端每次向服务器发出新请求时都会收到一个新的 AccessToken。此 AccessToken 归客户所有,并根据要求使用 Authorization header 进行转让。

我做的一个简单测试是从经过身份验证的客户端获取此访问令牌,然后使用来自另一台机器的简单 HTTP 请求将其发送到 Authorization header
结果这个新的"client"现在和原来的客户一样通过了身份验证,他可以随心所欲地提出请求。

所以问题是:
访问令牌未绑定到任何形式的客户端验证(如 session id 或客户端 IP 地址)。任何可以 get/find/steal/lookup 客户端 AccessToken 的请求都可以代表该客户端的假请求。

我研究了这个问题,但找不到任何人解决这个问题。也许我在验证客户端时做错了什么?我会喜欢一些见解。也许它是一个简单的配置,我错过了 out-of-the-box 解决方案。

谢谢!

这种攻击方式称为重放攻击。 This video by Professor Messer 解释重放攻击。

由于 Web 浏览器的透明性,您无法真正实现任何客户端(浏览器)来克服这个问题。

您可以做的是使用随机数实现摘要式身份验证。

In cryptography, a nonce is an arbitrary number that may only be used once.

基本实现如下所示。

  1. 用户请求 API 服务器。
  2. API 服务器以 HTTP 401 和 WWW-Authenticate header 中的随机数响应 [您必须跟踪随机数](带有随机数的 JWT 设置为过期在一个小 window 中,可能是 2 秒或更少会更好并且是无状态的。
  3. 客户端使用收到的随机数、客户端随机数和密码对请求进行签名,然后再次调用资源。
  4. API 服务器验证签名,如果签名有效则接受请求。
  5. 攻击者捕获请求并伪造用户。
  6. 由于随机数已过期/'used only once'攻击者的请求被拒绝。