您无法阻止 cookie第一次通过 HTTP提交,但您可以采取措施将由此造成的损害降至最低。基本原则是,您永远不会尊重通过 HTTP 提交的任何内容,并且无论何时收到明文形式的敏感信息,您都会将该信息视为已泄露。
将您的站点设置为从 HTTP 重定向到 HTTPS,并开始发送 Strict-Transport-Security 标头。(在您准备好之前,您不必进行预加载;我要说的无论如何都会起作用。)
然后,每当您看到通过明文 HTTP 提交的 cookie 时,都会使服务器端的所有这些 cookie 无效。此时不要试图将它们从浏览器的 cookie jar 中踢出,因为它不能保证工作有几个原因(明文 HTTP 响应无法操作标记为 Secure 的 cookie,旧浏览器可能会忽略 max-age=0 , 中间人可能会完全剥离 Set-Cookie 以使受害者继续使用受损的 cookie)。但是当它们出现在后续的 HTTPS 请求中时,不要尊重它们。此时(即仅当您建立了安全通道时),发出新的会话令牌并要求用户再次登录。
同样,如果您看到您的登录表单以明文形式提交,不要只是使会话 cookie 无效,锁定帐户。 不要将帐户恢复、登录或注册表单从 HTTP 重定向到 HTTPS;相反,发出一条错误消息,指示人们手动修复 URL(它就像一个验证码,但它是为了绕过 sslstrip 中的 URL 重写 ;-)。任何只有登录用户才能访问的页面在通过明文访问时应该重定向到首页,而不是 HTTPS 本身。
此外,请确保您的会话 cookie 既不可伪造又毫无意义。如今,大多数 Web 框架都会自动为您执行此操作,但如果您没有,最简单的构造是:每个会话 cookie 都是一个很大的(64 位可能就足够了,128 位就足够了)随机数,生成由加密安全的 RNG加上签名该号码的消息验证码。您可以为此使用对称 MAC,因为 cookie 只需要由站点进行身份验证,该站点是发布 MAC 的同一实体,因此它两次都知道相同的秘密。如果 cookie 带有无效的 MAC,请忽略它,不管你是如何得到它的——假装你根本没有得到它。(这甚至取代了关于使通过 HTTP 传入的 cookie 无效的规则。您不希望攻击者能够通过伪造请求来强制注销用户。)但是如果 MAC 是有效的,那么您使用随机数作为记录与用户会话相关的所有实际信息的数据库表的键。
在有人尝试登录之前,最好不要发布任何 cookie。这使得 MITM 更难获得有效的 cookie,也让您更容易遵守 GDPR。
在阅读了关于其他答案的讨论之后,我现在意识到 OP 关注一个非常特殊的场景:该站点的新用户第一次通过中间人访问它,该中间人正在终止 HTTPS,剥离退出 HSTS 并重写所有链接,并将未加密的站点转发给假设的新用户。与此相反,确实,唯一可能有帮助的是 HSTS 预加载。在没有 HSTS 预加载的情况下,新用户的帐户将“生而受到威胁”,攻击者将知道有关它的一切:不仅是会话 cookie,还包括用户名和密码,以及用于帐户的电子邮件地址恢复,以及受害者输入的每一点个人信息。这是令人讨厌的,唉,比你想象的更合理。
但是,如果您只有一次机会通过未被主动篡改的渠道与用户进行交互,您可以推送 HSTS 和安全会话 cookie,以上所有建议都会很有用。