某开源商城系统代码审计(脱敏版)

admin 2026-04-13 02:30:39 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文对某开源商城系统进行代码审计,发现其远程登录模块存在严重业务逻辑漏洞。系统在接收第三方登录凭证时仅进行base64解码和JSON解析,却未验证签名,导致攻击者可伪造凭证绕过认证,接管任意前台用户账户并覆盖余额、积分等敏感资产字段。建议增加签名校验机制并严格限制可信数据来源。 综合评分: 88 文章分类: 代码审计,漏洞分析,WEB安全,应用安全,安全开发


cover_image

某开源商城系统代码审计(脱敏版)

原创

仰恩网安校队 仰恩网安校队

GET不到的FLAG

2026年4月12日 13:42 福建

在小说阅读器读本章

去阅读

某开源商城系统代码审计(脱敏版)

本文仅记录代码审计思路。所有项目名称、接口路径、字段细节、版本信息、目标信息均已脱敏处理,不提供完整利用链和可直接复现的请求。

前言

最近在一次代码审计中,遇到了一处比较典型、也比较容易被忽略的业务逻辑问题。

漏洞点位于某电商系统的“远程登录 / 远程注册”模块。该模块的设计初衷是为了支持第三方系统同步用户身份,实现类似单点登录的效果。

从功能上看,这类接口并不罕见:

第三方系统生成用户身份数据 业务系统接收远程登录凭证 业务系统解析用户信息 业务系统创建或登录本地用户 业务系统签发本地登录态

但问题在于,代码实现中将外部传入的数据“解码”后直接作为可信身份使用,却没有完成最关键的“验签”步骤。

最终,该问题可导致攻击者伪造远程登录凭证,并在特定条件下获得指定前台用户的登录态,同时影响部分用户资料及资产相关字段。

漏洞类型

该问题属于业务逻辑与认证设计类漏洞,主要涉及:

远程登录凭证未验签 认证绕过 前台账号接管 用户资料污染 资产字段异常写入

严格来说,它不是传统意义上的注入、文件上传或命令执行,而是身份信任边界被破坏。

审计入口

审计过程中,首先注意到系统中存在一个远程登录相关接口。

该接口大致用于接收一个外部登录凭证,然后根据其中的用户信息创建或登录本地用户。

脱敏后的路由逻辑如下:

Route::get('remote_xxx', 'LoginController/remoteLogin');

该路由位于基础接口分组中,并未强制要求用户登录。

从业务语义上看,这类接口本身可以是公开接口,因为第三方登录入口通常需要在用户未登录时访问。

控制器逻辑

脱敏后的控制器代码如下:

publicfunction remoteLogin(Request $request) {     [$remoteToken] = $request->getMore([         [‘remote_token’, ”],     ],true);

    if($remoteToken == ”) {         return app(‘json’)->success(‘登录失败’,              ‘remote_login_url’ => sys_config(‘remote_login_url’)         );     }

    return app(‘json’)->success(         ‘登录成功’,         $this->services->remoteLogin($remoteToken)     ); }

  1. 从请求中读取远程登录凭证
  2. 判断是否为空
  3. 交给服务层处理

这里没有做签名校验,也没有做来源校验。不过很多项目会把核心校验放在服务层,因此继续向下跟进。

服务层关键逻辑

服务层中出现了本次审计的核心问题。

脱敏后的代码如下:

publicfunction remoteLogin(string$token = ”) {     $info = JwtTool::jsonDecode(         JwtTool::base64UrlDecode($token)     );

    $userInfo = $this->userDao->get([         ‘uid’ => $info->uid     ]);

    $data = [];

    if(!$userInfo) {         $data[‘uid’] = $info->uid;         $data[‘account’] = $info->phone ?:’out_’ . $info->uid;         $data[‘phone’] = $info->phone;         $data[‘password’] = md5(‘default_password’);         $data[‘nickname’] = $info->nickname;         $data[‘avatar’] = $info->avatar;

        $data[‘balance’] = $info->balance;         $data[‘points’] = $info->points;         $data[‘growth’] = $info->growth;

        $this->userDao->save($data);     } else {         $data[‘nickname’] = $info->nickname;         $data[‘avatar’] = $info->avatar;

        $data[‘balance’] = $info->balance;         $data[‘points’] = $info->points;         $data[‘growth’] = $info->growth;

        $this->userDao->update($info->uid, $data);     }

    return$this->createFrontendToken((int)$info->uid); }

真正危险的是这一段:

$info = JwtTool::jsonDecode(     JwtTool::base64UrlDecode($token) );

乍一看,代码里出现了 JwtTool,似乎和 JWT 相关。

但这里并没有执行 JWT 验签,只是做了:

base64url 解码 JSON 解析

这不是认证。

这只是解析用户输入。

“解码”和“验签”的区别

这是这类漏洞中最容易被忽略的地方。

很多开发者看到 JWT,容易产生一个误解:

只要能解析 JWT,就说明 JWT 是可信的

实际上并不是。

JWT 的安全性来自签名校验,而不是 base64 编码。

JWT 的 Payload 本质上只是 base64url 编码后的 JSON,任何人都可以构造和修改。

不安全逻辑:

$payload = jsonDecode(base64UrlDecode($token));

安全逻辑应该类似:

$payload = Jwt::verifyAndDecode($token, $secret, [‘HS256’]);

漏洞影响

该漏洞的影响主要分为三层。

第一层:绕过注册校验

如果远程凭证中的用户在本地不存在,系统会进入创建用户逻辑。

由于该流程不要求短信验证码、密码校验或人工确认,因此可能造成:

虚假手机号注册 批量创建异常用户 绕过正常注册风控

第二层:指定前台用户登录

如果远程凭证中指定的本地用户已经存在,系统会进入更新用户逻辑,并在最后签发该用户的前台 token。

这意味着攻击者可能通过伪造远程身份数据,获得指定前台用户的登录态。

第三层:敏感业务字段被覆盖

更严重的是,代码中并不只更新昵称、头像等展示字段,还更新了资产或权益相关字段。

脱敏后可以概括为:

余额类字段 积分类字段 成长值或等级类字段

这意味着攻击者伪造远程身份数据时,可能同时污染用户资产或权益数据。

如果业务系统中存在余额支付、积分抵扣、会员等级、分销佣金等功能,风险会进一步扩大


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:GET不到的FLAG 仰恩网安校队 仰恩网安校队《某开源商城系统代码审计(脱敏版)》

评论:0   参与:  0