bigywater.tech
Flask · 121

HttpOnly、Secure、SameSite

这三个 cookie 属性到底拦了什么?没写 SameSite 会怎样?跨站场景下什么配置才能带上 cookie?这篇不靠文档,用 localhost 与 127.0.0.1 这两个不同的站点在真实的 Chrome 里逐种配置跑一遍。

document.cookie
HttpOnly=True 时 JS 读到的是空
Lax
没有写 SameSite 的 cookie,Chrome 的默认处理
None + Secure
本次实验里唯一让跨站请求带上 cookie 的配置

在真实的 Chrome 里逐种配置

实测 · 本机执行输出
  [HttpOnly=True, SameSite 未设置]
     login                200
     js_cookie_visible    False
     js_cookie            (空)
     first_party_read     True
     cross_site_read      cookie sent: false
  [HttpOnly=False, SameSite 未设置]
     login                200
     js_cookie_visible    True
     js_cookie            session=<值>
     first_party_read     True
     cross_site_read      cookie sent: false
  [HttpOnly=True, SameSite=Lax]
     login                200
     js_cookie_visible    False
     js_cookie            (空)
     first_party_read     True
     cross_site_read      cookie sent: false
  [HttpOnly=True, SameSite=Strict]
     login                200
     js_cookie_visible    False
     js_cookie            (空)
     first_party_read     True
     cross_site_read      cookie sent: false
  [HttpOnly=True, SameSite=None(无 Secure)]
     login                200
     js_cookie_visible    False
     js_cookie            (空)
     first_party_read     False
     cross_site_read      cookie sent: false
  [HttpOnly=True, SameSite=None + Secure]
     login                200
     js_cookie_visible    False
     js_cookie            (空)
     first_party_read     True
     cross_site_read      cookie sent: true
  [HttpOnly=True, SameSite=Lax + Secure]
     login                200
     js_cookie_visible    False
     js_cookie            (空)
     first_party_read     True
     cross_site_read      cookie sent: false

上一篇:Session Cookie 安全属性;下一篇:CSRF 防护。

浏览器是本机的 Google Chrome 无头模式,两个站点分别是 127.0.0.1 与 localhost 上不同端口的 gunicorn 服务。第一次运行时跨站 iframe 偶尔没有返回结果,我给每种配置加了最多 4 次重试,并把无结果的运行丢弃。

分步演示

HttpOnly Secure SameSite
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动。本机 Google Chrome(无头模式)
    • 没有验证:真实 HTTPS 站点上的 Secure 行为(这里的 127.0.0.1 被 Chrome 当作安全上下文)、Firefox 与 Safari 的差异、SameSite=Lax 在顶级导航(点链接)里的放行、同站不同子域的 cookie 共享、第三方 cookie 弃用策略的影响
    京ICP备2026067502号-1京公网安备11010502063487号