首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
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
Coding
V2EX  ›  Python

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

  •  
  •   guyskk · 2016-03-30 11:49:05 +08:00 · 6052 次点击
    这是一个创建于 1353 天前的主题,其中的信息可能已经有所发展或是发生改变。

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


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