V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
matepi
V2EX  ›  程序员

请教一下关于 nonce 防重放

  •  1
     
  •   matepi · 2023-11-09 09:21:09 +08:00 · 3157 次点击
    这是一个创建于 385 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有一点没想明白,如果针对客户端是 web 页面的情况,那么 nonce 的生成算法,就一般都是在 web 端的 js 代码中了。

    这样相当于 nonce 的生成过程,仍然是对客户端暴露的,只要重放人有能力进行客户端 js 的分析与模拟运行,那不是 nonce 就失效了么?
    第 1 条附言  ·  2023-11-09 10:42:07 +08:00
    具体的需求是:

    一个系统具有多个较复杂的幂等查询功能,内部用户使用。
    但发现内部用户太多使用自动化手段、模拟正常用户登录,反复调用幂等查询,造成查询所占资源紧张。
    尤其是内部正常用户之间还会借用多账号等手段,增加自动化并发能力。
    希望通过一些手段控制,这些用户自动化重复调用、消耗系统资源的情况。

    现在大家对 nonce 的解释听下来,恐怕这个需求、并不是一个可以通过 nonce 防重放解决的需求?
    第 2 条附言  ·  2023-11-09 11:20:56 +08:00
    总结一下从楼里从大家这边学到的:

    nonce 防重放,要注意的,并不能解决正常用户重复自动化请求的问题。
    而是解决 mitm 等过程中,被截获请求后,以“简单”低成本,重复用户请求的情况。

    我所上述问题场景,个人理解还是有一些常见性的,现在看来
    不是防重放,和反爬有些关联又不相同,是不是应该定义一种新的场景、还是说有这样的场景轮子了呢?

    防自动化?优雅请求?用户配额限流?

    其中又需要具备的是什么技术
    限流;
    用户配额管理;
    对 WEB 日志等进行聚类分析等以发现自动化操作、并联动用户封禁/配额动态调整
    ……等等?

    有没有针对这样的,听上去是防重放、又有区别于防重放的场景,已有的轮子了呢?
    33 条回复    2024-06-21 13:53:11 +08:00
    LonnyWong
        1
    LonnyWong  
       2023-11-09 09:26:47 +08:00   ❤️ 2
    防重放不是说防用户重复请求,一般是防别人在网络上抓到你的包,然后重放。
    举个例子,你向 A 转账 10 元,并不是说你不能再向 A 转 10 元。防的是 A 把你的包抓了,不断地转 10 元。
    error451
        2
    error451  
       2023-11-09 09:30:50 +08:00
    一个 nonce 只能够请求一次,你抓到了 nonce 再一次请求是不可能成功的啊, 怎么可能进行重放攻击?
    你是不是混淆了 nonce ? nonce 不是 token 啊 , 不需要任何算法, 你自己手输入一个随机字符串也可以啊。没有人会对 nonce 校验,单纯的放一个列表里就行了。
    一个算法就做一件事情,nonce 就只防止重放攻击,其他的安全措施需要用其他的算法,别混淆。
    jinliming2
        3
    jinliming2  
       2023-11-09 09:31:24 +08:00 via iPhone
    即便是 web 页面,nonce 也是服务端下发的哇?
    matepi
        4
    matepi  
    OP
       2023-11-09 09:32:34 +08:00
    @LonnyWong 理解了。但这样也是假设在这个“别人”并没有对服务端客户端深度分析的情况下吧。如果这个“别人”是有心人,分析了这个 nonce 整体的交互和生成过程。那应该也是仍然可以实现重放的?

    又,如果要防用户的重复请求呢?尤其是查询类,没有类似金额控制类的情况呢。
    killerv
        5
    killerv  
       2023-11-09 09:36:25 +08:00
    有点记不太清楚了,nonce 应该是服务端发放的,随机的保证一段时间内不重复就行,这个只能用一次,客户端生成 nonce ,服务端也不认啊
    matepi
        6
    matepi  
    OP
       2023-11-09 09:36:44 +08:00
    @jinliming2 这意思是,nonce 是随着用户前一次请求,由服务器端返回客户端的,并在下一次请求中再带上服务端么?我看的理解还以为是都是客户端完全随机生成 uuid 或者带点 timestamp 之类的客户端算法生成?

    如果是服务器端生成,那对于分布式化的服务端,一是要搞个中心存储节点来存了吧?二是,这样会禁止掉在客户端开启多个 web 页面,并行操作的可能?
    retNu1l
        7
    retNu1l  
       2023-11-09 09:37:14 +08:00
    nonce 随机生成的,没有啥算法,没有签名情况下你随便改个字母都大概率命中不了重复校验。另外一般会对 once 同请求参数一起签名一下,增加逆向客户端及抓包篡改难度。
    tool2d
        8
    tool2d  
       2023-11-09 09:37:14 +08:00   ❤️ 1
    一般都是服务器返回的,你访问一下这个:

    https://acme-v02.api.letsencrypt.org/acme/new-nonce

    返回的头有 replay-nonce ,每次都会变,正常情况下客户端是无法生成的。

    那些能生成的,都是野路子。
    LonnyWong
        9
    LonnyWong  
       2023-11-09 09:41:21 +08:00
    @matepi nonce 是完全随机的,一次性的,知道怎么生成也没用。你说的别人分析交互过程,不是防重放,是防假冒,要用其他手段来解决。

    防重复请求,一般在请求前生成一个唯一的 ID ,后台要根据这个 ID 去重,前端要确保同一个请求的 ID 相同且全局唯一。
    tool2d
        10
    tool2d  
       2023-11-09 09:42:00 +08:00
    单纯客户端生成的,基于 timestamp 的签名,那种叫 Signature-Algorithm: HMACSHA256

    我尝试过想破解,但是是一个 APP ,并不是 web js 代码,难度就挺大的。
    matepi
        11
    matepi  
    OP
       2023-11-09 09:44:18 +08:00
    @retNu1l 这个签名如果是客户端做的,不是一样会能被搞掉的么?尤其 web 页面情况,js 代码都很好模拟的情况下
    matepi
        12
    matepi  
    OP
       2023-11-09 09:51:19 +08:00
    @LonnyWong “一般在请求前生成一个唯一的 ID ”这个何时、何侧、以何种算法生成的呢?按我之前理解是客户端,现在听大家的意思的理解,应该是在前一次请求、由服务器端、按服务器端内的算法生成的?

    “前端要确保同一个请求的 ID 相同且全局唯一。”我的理解,客户端前端只是把服务器端前一次下发的内容,在本次再带上服务器端的简单逻辑?客户端前端应该没有啥确保保证的能力吧。

    但如果是“在前一次请求、由服务器端、按服务器端内的算法生成的”;“并在本次再带上服务器”的逻辑的话,似乎这个逻辑就会限制了用户开多个 web 页面并行做请求的能力?
    vultr
        13
    vultr  
       2023-11-09 09:54:34 +08:00
    @matepi 8 楼 @tool2d 说的才是对的,nonce 得服务器返回才是安全的。
    tool2d
        14
    tool2d  
       2023-11-09 09:56:43 +08:00
    @matepi "似乎这个逻辑就会限制了用户开多个 web 页面并行做请求的能力?"

    前端有个幂等属性,关键 POST 操作肯定不能并行请求。

    如果是 GET ,那随便并行。
    matepi
        15
    matepi  
    OP
       2023-11-09 10:00:29 +08:00
    @tool2d 返回头的返回情况,如果一个正常用户,在前一个正常请求还没有完成、返回头还没有带回客户端的情况下,就并行进行第二次正常请求,这种情况怎么办呢?或是 ajax 异步请求提交并发交易、或是直接保留原页面以右键在新页面中打开的方式提交交易呢
    matepi
        16
    matepi  
    OP
       2023-11-09 10:02:21 +08:00
    @tool2d ……现在的需求就是要控制幂等交易(大开销查询)的正常用户但其做的模拟幂等交易。随便放行并不行啊……
    potatowish
        17
    potatowish  
       2023-11-09 10:07:31 +08:00 via iPhone
    客户端前端从服务端获取 nonce ,不管是通过接口返回还是返回头的方式,有心人都能获取新的 nonce
    LonnyWong
        18
    LonnyWong  
       2023-11-09 10:08:01 +08:00
    @matepi 简单的 UUID 就可以,按需求定制适用的方案。
    zliea
        19
    zliea  
       2023-11-09 10:09:52 +08:00
    防重放其实主要还是 timestamp ,nonce 只是加入随机,增加难度而已。
    cylx3124
        20
    cylx3124  
       2023-11-09 10:24:10 +08:00
    nonce 只是前后端签名验证的一部分, 一般通过 nonce + 时间戳 + 验签, 可以做到反爬虫和防止针对同一请求的重放。

    nonce + 时间戳 + 验签的方式, 只能增加伪造请求的难度, 不能完全杜绝伪造请求。因为不管是浏览器还是 app 端, nonce 获取和验签代码都是在客户端本地运行的, 有能力的人一定能破解你的 nonce 和 验签算法。

    B 站 app 就是典型的例子 https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/APP.md

    只有在后端做好风控、参数和业务逻辑的各种校验,才能真正做到接口的安全(服务器被攻击除外)。
    dyllen
        21
    dyllen  
       2023-11-09 10:25:57 +08:00
    @matepi 你是为了防止页面数据重复提交?这个随机字符串是服务器下发的,是直接渲染在页面里面的。
    szandy6
        22
    szandy6  
       2023-11-09 10:27:25 +08:00
    nonce 又不是加密算法生成的,它就是一个随机串,不存在暴漏问题。
    你可以理解为 nonce 保证只能请求一次,服务器会短暂保存请求过的 nonce ,下次再有人用这个 nonce ,就会被认为是重放。
    matepi
        23
    matepi  
    OP
       2023-11-09 10:30:08 +08:00
    @cylx3124 我的理解,风控、参数和逻辑校验,其实还是不能解决、正常用户的大开销的幂等查询类请求?类似于 DDoS 的请求行为?最终只能给用户上配额之类的?

    但配额也是有问题的,如果自动化查询者具备了很多用户账号,实际上还是能够挤占正常用户的额度?
    cylx3124
        24
    cylx3124  
       2023-11-09 10:39:26 +08:00
    @matepi

    这种需求如果有专业的风控团队,可以扔给风控团队去做,没有的话就只能根据 手机号、用户 id ,设备 id 、ip 等不同维度在服务端实现拦截了。

    真正的反爬虫是一种很难实现的目标,因为任何一种反爬虫的方法都可能被爬虫工程师找到绕过的办法。
    justplaymore
        25
    justplaymore  
       2023-11-09 10:49:38 +08:00
    nonce 是用来保证明文的不可预测性。

    当明文非常容易预测时:
    举例:
    请求 1 明文 money=10 ,签名 abc 。
    请求 2 明文 money=10 ,签名 abc 。
    请求 3 明文 money=10 ,签名 abc 。
    这 3 个请求的明文是相同的,非常好预测,没有随机性,那么攻击者收集足够多的请求样本后,就知道明文和密文的直接对应关系了,就可以得到一个明文和密文的字典了,类比彩虹表。

    当在明文中加上了 nonce ,保证不可预测性
    举例:
    请求 1 明文 money=10&nonce=q1w2e3r4 签名 1234
    请求 2 明文 money=10&nonce=5t4r3e2w1 签名 4567
    请求 3 明文 money=10&nonce=5t6y7u8i9 签名 6787
    虽然这 3 个请求中都是 10 元,但是明文不同,导致签名也不同,攻击者无法通过收集的样本,分析出明文 10 元和签名的关系。

    我是从不可预测性来解释 nonce 的作用,和具体的技术实现没有关系,和前端还是后端实现没有关系。
    proxytoworld
        26
    proxytoworld  
       2023-11-09 10:53:02 +08:00
    nonce 是防 mitm 的,至于你说的限制,得在服务端进行限流
    justplaymore
        27
    justplaymore  
       2023-11-09 10:57:35 +08:00
    一个系统具有多个较复杂的幂等查询功能,内部用户使用。
    但发现内部用户太多使用自动化手段、模拟正常用户登录,反复调用幂等查询,造成查询所占资源紧张。
    尤其是内部正常用户之间还会借用多账号等手段,增加自动化并发能力。
    希望通过一些手段控制,这些用户自动化重复调用、消耗系统资源的情况。

    看了你的需求,这不是 nonce 能解决的场景。
    对用调用量过多的情况,可以使用接口调用限流来控制,降低自动化调用的效率。
    对于复杂查询,可以从查询缓存,异步计算角度去考虑。
    opengps
        28
    opengps  
       2023-11-09 10:59:31 +08:00
    后端幂等性当然得靠后端进行,办法也非常简单,就是第一次有效执行结果的缓存重发就行了
    justplaymore
        29
    justplaymore  
       2023-11-09 11:00:00 +08:00   ❤️ 5
    lz 的提问方式是典型的 xy 问题。

    对于 X-Y Problem 的意思如下:

    1 )有人想解决问题 X
    2 )他觉得 Y 可能是解决 X 问题的方法
    3 )但是他不知道 Y 应该怎么做
    4 )于是他去问别人 Y 应该怎么做?

    简而言之,没有去问怎么解决问题 X ,而是去问解决方案 Y 应该怎么去实现和操作。于是乎:

    1 )热心的人们帮助并告诉这个人 Y 应该怎么搞,但是大家都觉得 Y 这个方案有点怪异。
    2 )在经过大量地讨论和浪费了大量的时间后,热心的人终于明白了原始的问题 X 是怎么一回事。
    3 )于是大家都发现,Y 根本就不是用来解决 X 的合适的方案。

    X-Y Problem 最大的严重的问题就是:在一个根本错误的方向上浪费他人大量的时间和精力!
    moya
        30
    moya  
       2023-11-09 11:19:27 +08:00
    nonce 防止 XSS 攻击
    gxm44
        31
    gxm44  
       2023-11-09 11:33:09 +08:00
    nonce 服务端下发,而且 js 无法读取到
    moya
        32
    moya  
       2023-11-09 11:36:12 +08:00
    @moya 看错忽略,以为说的是 script 标签
    chanlk
        33
    chanlk  
       160 天前
    @LonnyWong #1 我看有不少文章提到 https 就自带了防止网络层面抓包的重放,那么这个 nonce + 时间戳 的形式是否是多余的呢? nonce 这并不能防止恶意用户(脚本小子)的盗刷
    LonnyWong
        34
    LonnyWong  
       160 天前
    @chanlk #33 你再看看楼主的原始问题是什么
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3129 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 13:52 · PVG 21:52 · LAX 05:52 · JFK 08:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.