使用JWT编写带有Pyramid / Cornice的REST API进行身份验证,我必须实施一些CSRF保护。 在仔细阅读了这个主题之后,我理解了这个问题,但我对实现它的最佳方法感到很困惑,考虑到所有可能的攻击向量,它有点棘手。
由于此API可以访问敏感数据并将作为开源软件发布,因此需要一个独立的保护。它将用于具有不受信任的子域的环境中,我不能依赖用户遵循安全准则。
对于我的无国籍服务,我可以使用" Double Submit Cookies"或者" Encrypted Token Pattern" -method。
要防止"cookie tossing",Double Submit方法中的令牌需要是可验证的。 MiTM attacks是一个额外的威胁,我希望通过仅强制使用HTTPS-cookies来充分缓解这种威胁。
要获得一个无法通过攻击者轻易猜到并复制的可验证令牌,我想像这样的哈希标记应该可以正常工作:
pbkdf2_sha256.encrypt($userid + $expire + $mycsrfsecret, salt=$salt)
"&EXP#34;是JWT的到期值。 JWT将与CSRF-cookie和" exp"一起发布。可以被服务器读取,它增加了一些额外的保护,因为它的变量和攻击者都不知道它(可能是多余的?)。
根据请求,我可以轻松地比较我收到的两个令牌,并使用pbkdf2_sha256.verify($tokenfromrequest, $userid + $exp + $mycsrfsecret)
将其与JWT令牌中的值进行比较(' Verifiablity')。
这种方法会遵循建议的做法吗?
我已经选择pbkdf2 over bcrypt,因为它的验证方法明显更快。
到期将设置为7天,之后JWT和CSRF令牌将通过新登录续订(它们也将在中间重新登录时续订)。
The alternative是向客户端发送一个字符串,由userid,expiry和nonce组成,用服务器端密码加密。在请求中,此字符串将被发送,服务器可以对其进行解密并验证用户ID和到期日期。
这似乎是一种更简单的方法,但我不确定如何实现它,我不打算推出自己的加密,我没有找到好的例子:
答案 0 :(得分:1)
使用JWT编写带有Pyramid / Cornice的REST API进行身份验证
虽然我不熟悉这些框架,但我建议您确保JWT令牌在HTTP头(例如My-JWT-Token: ...
)内传递,而不是cookie。然后您不必担心CSRF向量。
跨站点请求伪造是一个问题,因为浏览器的性质总是倾向于将cookie(通常包含身份验证信息)提交到特定域。浏览器不会自动提交自定义标题,您不必担心。
Double Submit Cookies
您的方法过于复杂,您只需使用GUID即可。将该GUID放入cookie中,并将其放入请求的任何其他部分。如果他们相等,CSRF检查通过。您还可以将GUID放入JWT,然后验证GUID也在标题/正文/查询参数中。
加密令牌模式
这几乎就是JWT,只需按照建议的标题传递令牌
回答问题:
hmac
与import hmac
一样。我不打扰加密,只是确保令牌中没有敏感信息。其他PyCrypto也可以帮到你。