使用安全的、HTTPOnly 的 SameSite cookie(比如,超时时间很短)来存储 state 参数的值是否安全?
你可以让它安全。
假设您正在编写服务器端软件(我假设您这样做,因为您提到为 cookie 设置 HTTPOnly 选项):加密服务器上的状态参数并将加密值存储在 cookie 中。(详细信息:确保使用带有随机 iv 的安全加密算法,并且不要使用 ecb 模式)。确保在服务器上保持加密密钥的安全。
为什么要加密cookie?
您必须加密状态值(或整个 cookie)有两个原因:
原则上:安全人员喜欢分层他们的安全措施。如果一个失败了,另一个仍然会保护你。即使您使用 SSL 保护您的流量,SSL 加密也可能会受到影响。例如,在我工作的地方,我们有一个内容检查防火墙,它在 SSL 上执行 MITM,因此它通过设计破坏了连接的安全性。(总而言之,这是一个非常糟糕的主意,但我相信这很常见 - 这意味着您不能指望 SSL 保护从服务器到客户端的连接。
保护来自客户端(用户代理)的状态值。如果您的客户端上有恶意软件,您不想将状态值暴露给它。可能会被偷。如果状态值是加密的,客户端软件就无法访问它,这很好。
这安全吗?
这与在 cookie 中存储会话 id 然后使用会话 id 作为服务器端数据库表的索引一样安全,因为浏览器、浏览器中的恶意 javascript 和其他任何人都不会看到任何不透明的东西, 加密 cookie 中的随机字符串,如果他们以任何方式弄乱它,它不会解密为原始状态值,这将导致状态验证失败。但是您可能想要添加一个 MAC(消息身份验证代码),并且仅在 MAC 检出时触摸 cookie 中的加密状态值,以保护您的 cookie 内容免受干预。
本地浏览器内 javascript 与服务器端处理
如果您正在编写发出 oauth 请求的浏览器 javascript,则必须格外小心(但 javascript 浏览器的安全性从根本上被破坏了;如果您有一个 javascript 浏览器应用程序执行 oauth 请求,我怀疑您能否使其真正安全 - 您可以它相当安全,但可能无法抵御坚定的对手。
验证状态参数是否足够?
使用 state 参数中的值验证 cookie 中的值是否足以验证请求的有效性?
验证状态是否足以验证 oauth 请求(回复?)取决于您使用的流程以及您在协议中的哪个步骤。
例如,如果您要取回一个 jwt id 令牌,在几乎所有情况下,您都必须验证 id 令牌以确保它是有效的并且适合您(您可以自己执行此操作或将其发送到验证端点。 jwt id 令牌经过数字签名,您必须确保签名正确、受众和您的客户端 id 匹配、令牌未过期等)。
访问令牌也是如此:例如,如果您不验证访问令牌的受众,则可能会发生不好的事情(例如,访问令牌可能用于另一个客户端......)
在某些情况下,您不需要验证令牌。当您使用 open id connect 从身份提供者获取 id 令牌并且您不通过浏览器路由请求,并通过服务器端请求从身份提供者取回 id 令牌时,我认为您可以信任 id 令牌而不进行验证。但是,我仍然总是验证,只是为了确保我不会因自己的聪明而跌倒;-)