推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
guyskk
V2EX  ›  Python

设计无状态验证码,大家看下是否可行,有没有什么漏洞?

  •  
  •   guyskk ·
    guyskk · Mar 30, 2016 · 8733 views
    This topic created in 3709 days ago, the information mentioned may be changed or developed.

    无状态验证码不需要在 SESSION 中保存数据,流程如下:

    1. 服务端先配置一个密钥 KEY
    2. 客户端请求验证码 TOKEN, 服务端生成一个随机字符串 TEXT ,再生成一个 SALT ,用 KEY 和 SALT 对 TEXT 进行加密 加密后的 TEXT 和 SALT 拼接到一起,作为 TOKEN 返回给客户端
    3. 客户端请求验证码图片,携带验证码 TOKEN, 服务端根据 KEY 和 TOKEN 中的 SALT ,解密出 TEXT ,用这个 TEXT 生成一幅图片
    4. 客户端发送业务请求,携带验证码 TOKEN 和用户输入的 CODE, 服务端根据 KEY 和 TOKEN 中的 SALT ,解密出 TEXT ,和 CODE 比对

    代码 https://github.com/guyskk/kkblog/blob/master/kkblog/captcha.py

    大家看下是否可行,有没有什么漏洞?

    31 replies    2016-06-23 13:18:38 +08:00
    jedyu
        1
    jedyu  
       Mar 30, 2016
    把 Session 中的数据挪到了 Token 中而已
    cxh116
        2
    cxh116  
       Mar 30, 2016
    你要明白 session 的 id 不过是存在 cookie 里面的一个 token 而已.
    guyskk
        3
    guyskk  
    OP
       Mar 30, 2016
    @jedyu 是的,这样服务器就不需要保存 Session ,客户端也可以不用 Cookie
    Archangel_SDY
        4
    Archangel_SDY  
       Mar 30, 2016   ❤️ 4
    这个验证码没有有效期,并且可以多次使用? 那我始终拿一组 Token 和 Code 去刷就可以了呗.
    loading
        5
    loading  
       Mar 30, 2016 via Android
    jugelizi
        6
    jugelizi  
       Mar 30, 2016   ❤️ 1
    哈后 4L 一脚踢坏了楼主的轮子
    guyskk
        7
    guyskk  
    OP
       Mar 30, 2016
    @Archangel_SDY 确实是。在第 2 步中,随机字符串 TEXT 后面再加上有效期应该可以。验证码在有效期内可以重复使用。
    ybdhjeak
        8
    ybdhjeak  
       Mar 30, 2016
    直接把 code 加密写进 cookie 不就行了,下次让客户端带着 cookie 和验证码一起来
    guyskk
        9
    guyskk  
    OP
       Mar 30, 2016
    @guyskk 有效期 1~3 分钟
    ybdhjeak
        10
    ybdhjeak  
       Mar 30, 2016
    你的 token 和 cookie 没啥区别吧,只不过是传递方式不同, session id 也可以用参数形式传递啊
    xiaolanglang
        11
    xiaolanglang  
       Mar 30, 2016   ❤️ 1
    @guyskk 不加仅能使用一次的限制,验证码就形同虚设,对于暴力提交请求的程序来说, 1 分钟识别一次验证码相当于没有验证码
    keller
        12
    keller  
       Mar 30, 2016
    有效期内这个验证码不就可以无限使用啊?
    chac88
        13
    chac88  
       Mar 30, 2016
    应该携带一个应用的 id,有效时间是多少,当下次刷新时,自动将该应用 id 的验证码删掉,
    反正就是要保证验证码只能用一次。 不然还叫什么验证码
    dndx
        14
    dndx  
       Mar 30, 2016
    目测有效期内可以重放,对机器人来说还是很方便的。
    knightdf
        15
    knightdf  
       Mar 30, 2016
    这不是一次性的验证码。。。
    menc
        16
    menc  
       Mar 30, 2016
    没有漏洞,而且是业界一直在采用的方案。。
    不过业界把这个东西叫做 csrf token ,因为这样一次性的 token 可以防止 csrf 攻击,
    事实上,如果 token 用后即扔的话,用不着对 token 这么大张旗鼓的做手脚
    knightdf
        17
    knightdf  
       Mar 30, 2016
    @menc 大哥,你是混哪个业界的?好屌
    flowfire
        18
    flowfire  
       Mar 30, 2016
    何必呢。。。
    cheneydog
        19
    cheneydog  
       Mar 30, 2016
    1. 服务端的密钥 KEY 是全局的所有用户所有请求都一样
    2. 加密后的 TEXT 和 SALT 拼接到一起返回,相当于暴漏了 SALT
    有一定的被猜解的可能性。


    也不觉得比加密后写入 cookie 有什么优势。
    wlsnx
        20
    wlsnx  
       Mar 30, 2016
    有点奇怪,为了避免保存数据,所以每次都生成新数据,逻辑更复杂了。
    qiyuey
        21
    qiyuey  
       Mar 30, 2016
    你只是做了一个简化版的 session
    shade
        22
    shade  
       Mar 30, 2016
    OAuth 也是这样的吧
    cevincheung
        23
    cevincheung  
       Mar 30, 2016
    @wlsnx web 集群解决 session 一致性
    Abirdcfly
        24
    Abirdcfly  
       Mar 30, 2016 via iPhone
    @knightdf 我觉得他说的没错啊。默认是 cookie 来做这些事情。有的禁止 cookies ,不就用的是这个方案?
    zwzmzd
        25
    zwzmzd  
       Mar 30, 2016   ❤️ 1
    ddou
        26
    ddou  
       Mar 30, 2016
    @zwzmzd 内容不错,非常感谢。
    shade
        27
    shade  
       Mar 31, 2016
    webhook 是什么?
    guyskk
        28
    guyskk  
    OP
       Mar 31, 2016
    @shade kkblog 代码里面的吗,那个是 github 的开放接口
    playsoso
        29
    playsoso  
       Jun 23, 2016
    我觉得可以使用 jwe 方案 ,也就是 jwt 其中客户端内容加密过 , 请求验证码同时 发放 token , 提交验证码时携带 token
    通过 token 里 签发时间和过期时间来判断是否有效 , token 内容与验证码结果做比对
    playsoso
        30
    playsoso  
       Jun 23, 2016
    @playsoso 因为涉及到重放攻击,而且验证码有状态 服务端需要记录是否发放过验证码 和 验证码是否已验证过,所以还是需要依赖服务端 状态保存
    guyskk
        31
    guyskk  
    OP
       Jun 23, 2016 via Android
    @playsoso 要保证验证码只能用一次,服务端必需要有状态,所以无解。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3453 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 140ms · UTC 10:44 · PVG 18:44 · LAX 03:44 · JFK 06:44
    ♥ Do have faith in what you're doing.