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

支.付宝收到异步回调后有必要再主动向支.付宝发一个请求确认订单状态吗?

  •  
  •   LLaMA · 347 天前 · 3198 次点击
    这是一个创建于 347 天前的主题,其中的信息可能已经有所发展或是发生改变。
    46 条回复    2023-05-06 10:11:25 +08:00
    jaydenhpj
        1
    jaydenhpj  
       347 天前
    如果对异步回调的参数验证了签名,就不需要了。
    moult
        2
    moult  
       347 天前
    异步回调里面还有一个 notifyId 参数的,建议验签之后,再验证一下 notifyId 即可。
    LLaMA
        3
    LLaMA  
    OP
       347 天前
    补充:一个外包的商城系统有 30 多笔款项对不上,检查日志后发现同步通知接口被多次伪造 method=alipay.trade.wap.pay.return 的请求,研究了 3 天也没找到这是怎么做到的,只能加主动查单了,异步接口在研究有没有必要加
    LLaMA
        4
    LLaMA  
    OP
       347 天前
    @benrezzagmehamed #3 伪造的同步通知请求验签可通过,查不到任何资料这怎么伪造
    LLaMA
        5
    LLaMA  
    OP
       347 天前
    @moult 不验证 notifyId ,只验证订单状态是否是已付款会有什么风险吗
    jenlors
        6
    jenlors  
       347 天前
    @benrezzagmehamed 密钥泄露了?
    bootvue
        7
    bootvue  
       347 天前
    有内鬼 停止交易
    awolf
        8
    awolf  
       347 天前
    签名也能伪造?确认支付单号都是不一样的?(或者说是全新生成的?)
    dem0ns
        9
    dem0ns  
       347 天前
    肯定要验证啊,回调只是通知,没收到通知也得定时主动验证
    optional
        10
    optional  
       347 天前 via iPhone
    异步通知已经是异步请求了,增加一个验证又不会影响你的体验,加。
    silypie
        11
    silypie  
       347 天前
    一般两个都要实现
    kcnine
        12
    kcnine  
       347 天前
    多半是代码和密钥都被泄漏了,做做安全检查吧,不然不可能通过签名的
    lower
        13
    lower  
       347 天前
    我之前接手过一个系统,支付回调里连支付状态是不是 success 都没判断,直接就拿 id 更新订单状态了,😂幸亏财务一直在一笔笔的核对
    sujin190
        14
    sujin190  
       347 天前 via Android
    @benrezzagmehamed 密钥泄露了这不随便就能弄了
    LLaMA
        15
    LLaMA  
    OP
       347 天前
    @jenlors
    @kcnine
    @sujin190 ???看的我都怀疑我了,你们真的有接过支.付宝吗?签名用的是支.付宝私钥,商家根本没有获得支.付宝私钥的权限,这怎么泄露?如果是代码里用于验签的支.付宝公钥被偷改了那正常的支付请求我们就收不到了,所以应该不存在这种可能
    bestie
        16
    bestie  
       347 天前
    既然私钥不可能泄漏,那只能是同步通知的处理有问题。如果暂时查不出来就同时接入下异步通知吧,保证业务稳定再慢慢排查代码哪里有漏洞。
    Crawping
        17
    Crawping  
       347 天前
    你确认了订单号么? 签名怎么伪造
    LLaMA
        18
    LLaMA  
    OP
       347 天前
    @Crawping 确认了
    haha512
        19
    haha512  
       347 天前
    伪造有难度,不代表不能伪造


    比如 订单

    return_url=http://xxx.com/notify&out_trade_no=12345&seller=alice&total_fee=100&sign=XXX,

    攻击者可以通过修改 return_url 到掌控的地址,如 http://bbb.com/,提交请求:

    return_url=http://bbb.com/notify&out_trade_no=12345&seller=alice&total_fee=100&sign=XXX

    来获得 return_url 的结构。再伪造以下消息签名后发送给商户,伪造通知

    target_url: http://xxx.com/notify

    post_data: put_trade_no=12345&seller=alice&total_fee=100&trade_status=SUCCESS&sign=XXX.

    商户收到消息后验证签名正确,所有参数均正确,将完成攻击者的订单。而事实上并未进行过任何支付。
    haha512
        20
    haha512  
       347 天前
    在异步通知里更新订单状态,不要在同步通知里更改
    LLaMA
        21
    LLaMA  
    OP
       347 天前
    @haha512 改 return_url 需要商户私钥签名,假设商户私钥泄露了,如果攻击者不支.付,支.付宝也不会给攻击者签名 return 的数据,如果攻击者换成自己的收款账号那 appid sellerid 之类验证都过不了了
    jenlors
        22
    jenlors  
       347 天前 via iPhone
    感觉是不是代码里面验签逻辑的问题,建议好好看看代码。另外不要完全依赖同步接口,因为用户可能支付完成直接关掉界面不进行跳转。
    wqhui
        23
    wqhui  
       347 天前
    是不是代码逻辑有 bug ,支付宝印象中是 rsa 的签名,私钥只在支付宝平台那边,其他人改参数后没有重新生成签名,签名就对不上了
    Felldeadbird
        24
    Felldeadbird  
       347 天前
    日订单数量不多,财务又勤快校验的话可以信任异步回调。

    反之将回调的信息发给支付宝确认订单状态是为了避免回调被人恶意发起,实现伪造支付请求。
    haha512
        25
    haha512  
       347 天前
    return_url 并不参与签名。
    异步通知的 url 需要在支付宝控制台填写,会验证。所以异步里更新订单是比较安全的。
    skyrem
        26
    skyrem  
       347 天前
    支付宝有很多支付产品,当面付 和 手机网站支付 接入上都差不多,回调体也差不多,我记得 手机网站支付 如果用户取消也会有回调,只是状态码不一样
    changepll
        27
    changepll  
       347 天前
    在异步中,查一下订单状态是必要的。 这样伪造都没办法伪造。
    不用查的前提是代码,密钥之类的没有出现泄密
    azui999
        28
    azui999  
       347 天前
    支付宝
    kcnine
        29
    kcnine  
       347 天前
    @LLaMA 支付宝的私钥当然不太可能泄漏,我是怀疑你们程序都被加了后门了,或者代码本身就有漏洞
    justfindu
        30
    justfindu  
       347 天前
    确认就是你们系统出现了 bug. 不要怀疑自己. 我之前也看到群里有个人说这个问题. 就是被绕过去了
    lopssh
        31
    lopssh  
       347 天前 via Android
    肯定要验证啊,回调只是通知,没收到通知也得定时主动验证。
    异步通知已经是异步请求了,增加一个验证又不会影响你的体验,加。
    一般两个都要实现。
    我之前接手过一个系统,支付回调里连支付状态是不是 success 都没判断,直接就拿 id 更新订单状态了,😂幸亏财务一直在一笔笔的核对。
    vcbal
        32
    vcbal  
       347 天前
    @LLaMA 他们是说商家私钥有没有丢啊。。你们要是还没加白名单 ip 的话,配置被盗了,劫持请求不就是实现你说的这个情况
    lopssh
        33
    lopssh  
       347 天前 via Android
    return_url 并不参与签名。
    异步通知的 url 需要在支付宝控制台填写,会验证。所以异步里更新订单是比较安全的。

    支付宝有很多支付产品,当面付 和 手机网站支付 接入上都差不多,回调体也差不多,我记得 手机网站支付 如果用户取消也会有回调,只是状态码不一样。

    在异步中,查一下订单状态是必要的。 这样伪造都没办法伪造。
    不用查的前提是代码,密钥之类的没有出现泄密。
    vcbal
        34
    vcbal  
       347 天前
    @LLaMA 同步的接口 不去请求一下订单状态吗?这个是代码逻辑问题吧
    Anivial
        35
    Anivial  
       347 天前
    “伪造的同步通知请求验签可通过”,问题不是很明显了吗?
    1. 支付宝私钥泄露
    2. 你的验签代码有问题
    那你觉得哪个可能大呢?如果你都换成同步,那订单数量多了之后怎么办,而且你代码上的漏洞还是没解决
    vZexc0m
        36
    vZexc0m  
       347 天前
    异步通知验签过了基本没有问题。排查下自己代码问题。支付宝异步通知时未收到正常 response 会重复发起异步通知。
    楼上说更改 URL 的不成立,因为所有参数都要参与签名。
    brader
        37
    brader  
       347 天前
    楼主,不管是你代码问题,还是支付宝或你们导致的资料泄露,反正都是有人盯上你们了,其他措施你该怎么补救怎么补救,我给你一个额外的建议:
    你尽快更换回调地址的 url 吧,不然一直有人知道你回调 url ,骚扰你,也挺烦的。你可以换成如: https://xxx.com/callback/bdxZYgAHF1V2yCMD 这样的地址,后面加了一串随机字符串,注意:这个策略不保证你的接口安全,仅是让攻击者不那么容易找到你的回调 url ,避免大部分麻烦。
    LLaMA
        38
    LLaMA  
    OP
       347 天前
    @Anivial 支.付宝私钥商家根本接触不到,验签用的是支.付宝官方提供的示例代码
    @azui999 v 站注册 180 天才能发这个词
    @lopssh 如果用户取消也会有回调 我也怀疑是用类似这种的方法,一直无法复现成功
    Anivial
        39
    Anivial  
       347 天前
    @LLaMA #38 官方验证只是能证明参数加密没有错误,你有完整对比订单号,appid 这些信息吗?
    官方的文档:
    商家需要验证该通知数据中的 out_trade_no 是否为商家系统中创建的订单号。
    判断 total_amount 是否确实为该订单的实际金额(即商户订单创建时的金额)。
    校验通知中的 seller_id (或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方(有的时候,一个商家可能有多个 seller_id/seller_email )。
    验证 app_id 是否为该商家本身。

    如果这些信息都能被伪造,我只能说你的网站真的很有价值,能被呢么大手笔来攻击
    ytmsdy
        40
    ytmsdy  
       347 天前
    @LLaMA
    要么是 key 泄露了,要么是有内鬼。
    支付成功的通知的逻辑是经历了这么多年,每年这么大数量的交易,不太可能出问题的。
    buffzty
        41
    buffzty  
       347 天前   ❤️ 2
    不用怀疑支付宝私钥泄露.
    应该是对方真的支付了,但是你们漏了 导致对账错误
    别再错误的路上瞎走
    bjzhush
        42
    bjzhush  
       347 天前   ❤️ 1
    泄露个毛线啊,先理清流程吧
    正常流程来说,发起支付用户只能看到 return url ,就是用户支付完了跳到的提示页面
    至于支付成功之后,支付宝回调商家,那个回调通知的 URL ,只要你自己不泄露,从某些角度来说除了支付宝别人不可能知道的
    都看到了所谓的被伪造的请求了,就没去查查发这些请求的 IP 到底是不是支付宝的?没去看看是不是处理回调失败导致支付宝重试的?没去检查下自己代码是不是有问题?
    simonlu9
        43
    simonlu9  
       347 天前
    肯定要再次去支付宝获取一下订单是否真的充值成功,回调签名是支付宝私钥加密的,别人可以用支付宝公钥解密,但绝不能伪造。再次检查下代码吧
    simonlu9
        44
    simonlu9  
       347 天前
    最好在数据库在加一个支付凭证的唯一索引,不然会导致重复充值问题,客户端支付成功->服务端确认;支付宝回调-》服务端确认订单;我之前遇到这两个同时并发,结果多充了两笔
    Kinnice
        45
    Kinnice  
       347 天前
    一般的实现基本是只依赖异步回调的接口结果,同步接口只是做个跳转,你这正好反过来。
    WindProtect
        46
    WindProtect  
       346 天前
    你收的的是重复的回调么?有没可能是因为支付宝的通知回调然后你们这边没有应答然后他们重试了?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3992 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 10:26 · PVG 18:26 · LAX 03:26 · JFK 06:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.