bigywater.tech
Flask · 120

Session Cookie 安全属性

Flask 的 session cookie 默认安全吗?每个配置项到底改了什么?过期是怎么算的?cookie 太大会怎样?这篇逐项读出真实的 Set-Cookie 头,并用 curl 验证 Secure。

HttpOnly
Flask 默认开启的唯一一个安全属性
4093
浏览器通常的 cookie 长度上限(字节),超过会被悄悄忽略
Vary: Cookie
读了 session 的响应里自动加的头

默认的 Set-Cookie

实测 · 本机执行输出
   ['session=<值>', 'HttpOnly', 'Path=/']

上一篇:SECRET_KEY 的用途;下一篇:HttpOnly、Secure、SameSite。

配置项与属性

实测 · 本机执行输出
  SESSION_COOKIE_SECURE=True                   → ['session=<值>', 'Secure', 'HttpOnly', 'Path=/']
  SESSION_COOKIE_HTTPONLY=False                → ['session=<值>', 'Path=/']
  SESSION_COOKIE_SAMESITE='Lax'                → ['session=<值>', 'HttpOnly', 'Path=/', 'SameSite=Lax']
  SESSION_COOKIE_SAMESITE='Strict'             → ['session=<值>', 'HttpOnly', 'Path=/', 'SameSite=Strict']
  SESSION_COOKIE_SAMESITE='None'(没配 Secure)    → ['session=<值>', 'HttpOnly', 'Path=/', 'SameSite=None']
  SESSION_COOKIE_NAME='__Host-sid' + Secure    → ['__Host-sid=<值>', 'Secure', 'HttpOnly', 'Path=/']
  SESSION_COOKIE_PATH='/app'                   → ['session=<值>', 'HttpOnly', 'Path=/app']
  SESSION_COOKIE_DOMAIN='.example.com'         → ['session=<值>', 'Domain=example.com', 'HttpOnly', 'Path=/']
  SESSION_COOKIE_PARTITIONED=True              → ['session=<值>', 'Secure', 'HttpOnly', 'Path=/', 'Partitioned']

permanent 与过期

实测 · 本机执行输出
  不设 permanent                         → ['HttpOnly', 'Path=/']
  session.permanent=True(默认 31 天)      → ['Expires=Mon, 02 Nov 2026 05:27:40 GMT', 'HttpOnly', 'Path=/']
  PERMANENT_SESSION_LIFETIME=1 小时      → ['Expires=Fri, 02 Oct 2026 06:27:40 GMT', 'HttpOnly', 'Path=/']

续期与 Vary

实测 · 本机执行输出
  非 permanent,只读请求                           → 响应里有 Set-Cookie: False
  permanent,只读请求(默认 REFRESH=True)            → 响应里有 Set-Cookie: True
  permanent,只读请求,REFRESH=False               → 响应里有 Set-Cookie: False
  不碰 session 的请求有没有 Vary: Cookie: None
  读了 session 的请求:Vary = Cookie

cookie 太大

实测 · 本机执行输出
  session 里放 1000 字节 → Set-Cookie 长度 830 | 警告:无
  session 里放 5000 字节 → Set-Cookie 长度 3905 | 警告:无
  session 里放 7000 字节 → Set-Cookie 长度 5454 | 警告:The 'session' cookie is too large: the value was 5428 bytes but the header required 26 extra bytes. The final 
  session 里放 9000 字节 → Set-Cookie 长度 7034 | 警告:The 'session' cookie is too large: the value was 7008 bytes but the header required 26 extra bytes. The final 

Secure 的验证

实测 · 本机执行输出
  test client 在 http 下登录后读 session → {'u': 'ann'} (test client 不检查 Secure,不能用它验证这个属性)
  SESSION_COOKIE_SECURE=False:Set-Cookie 带 Secure = False;之后 curl 经 http 带着 cookie 罐请求 /read → {"u":"ann"}
  SESSION_COOKIE_SECURE=True:Set-Cookie 带 Secure = True;之后 curl 经 http 带着 cookie 罐请求 /read → {"u":"ann"}

下一篇会专门看这三个属性的含义与浏览器行为。

分步演示

Session Cookie 安全属性
本步的对象

    本文用到的工具与边界

    • 本机 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,数字每次运行会有小幅抖动。curl 8.7.1
    • 没有验证:浏览器里各属性的实际拦截效果(下一篇用真实浏览器验证)、SameSite=None 不带 Secure 时浏览器的拒绝、__Host- 前缀在浏览器里的强制规则、服务端 session(Flask-Session)的 cookie 行为
    京ICP备2026067502号-1京公网安备11010502063487号