替别人打卡之前,我先看穿它藏在前端的那把钥匙

admin 2026-09-01 04:38:22 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文复盘了某银行考勤系统的未授权漏洞挖掘过程。核心问题在于前端JS硬编码鉴权参数,导致匿名请求可调用所有业务接口。攻击者可实现代打卡、修改签名、批量读取考勤及客户留言等操作,构成完整攻击链。修复需从网关统一鉴权、服务端签发凭据及操作归属校验三方面入手。 综合评分: 88 文章分类: 漏洞分析,实战经验,SRC活动,WEB安全,安全建设


替别人打卡之前,我先看穿它藏在前端的那把钥匙

学点安全吃早餐

2026年8月27日 12:29 福建

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

企业 SRC 漏洞挖掘实例复盘 · 某股份制银行总行考勤系统(单位、域名、真实工号与凭证值已脱敏)

01

一句话:这是个什么样的洞

一次常规测试,我撞上了这家银行总行的考勤系统。这套系统的网关注册了一堆业务接口,可整个鉴权只靠写死在前端 JS 里的一个固定参数——人人可见、对全接口共用。

结果就是:不需要任何登录,任意请求就能抵达这些业务接口。由此拉出一条完整的未授权链——

· 替任意员工代签到 / 代签退,写入还能查回验证(写);

· 改任意员工个性签名(写);

· 批量读员工考勤,精确到秒、带迟到/休假(读);

· 读任意员工客户留言,含客户标识与评价(读)。

这不是单个越权,是一条「未授权 = 写 + 读全通」的完整链。

02

从哪下手:读 JS,接口和钥匙都在里面

考勤系统在移动端走 H5,前端代码直接发给你,不用逆向。所以第一步永远是:把打包 JS 翻一遍。

这一翻,三样关键信息全出来:

① 网关入口:所有业务走同一个 POST 入口,靠请求参数 uri 路由到方法(形如 POST {域名已脱敏}/openapi/…/invoke.jsp);

② 硬编码凭证:一个像“秘密”的固定值,每个请求都塞同一份;

③ 接口名单:签到、签退、查考勤、查签名、查留言,全列在里面。

接下来先画“信任模型”:这套系统的身份验证,是服务端校验会话,还是只信客户端塞进来的固定值?答案很明确——匿名即可达,身份靠前端塞值 = 匿名即全权

剩下的问题只剩一个:这些裸奔接口,能写吗?写得到底吗?于是进复现模块。

03

复现:这条链,6 步走完

下面的复现全部用一个授权范围内的测试工号走最小验证,证明“能写”后就还原,不碰任何真实他人数据。

1先封“写”:给一个工号代签到 / 代签退

接口:bus.pushAttendanceSignInInfo(签到)/ bus.pushAttendanceSignOutInfo(签退) 方法:POST,网关入口,参数 uri 指定方法,内容含 工号 AcctNo、打卡点、设备号 EqmtNo、状态 St

四步最小验证:①查基线(该工号当前状态)→ ②代签到 → ③查回验证(状态翻成“已签到”、时间写入具体时:分:秒)→ ④代签退(状态再翻)。能写、还能查回,闭环成立。

这是完整性攻击:不偷账号,却能替你写记录。考勤连着考核、绩效、发薪,一旦能伪造,整条线可信度归零。

2换对象再写:改个性签名

接口:bus.setSignInfoByNotesid(写入)/ bus.querySignInfo(验证) 参数:标识 notesId、签名内容 sign_info

同上闭环:先查(空)→ 写入(“设置成功”)→ 再查(变我写的那串)→ 还原为空。签名是员工对内展示的“形象”,能改一人就能批量改,已是任意用户首屏篡改级别。

3顺藤摸瓜:批量读考勤

接口:bus.getAttendanceRecordList 参数:工号 AcctNo(无归属校验),返回某段时间出勤:签到/签退时间、当天状态(正常/迟到/休假)

员工工号是有规律的连续段,抓一段枚举命中率,一个段就掘出几十位员工有效考勤——有人被标“迟到”、有人连轴加班、有人“休假”,对内部高度敏感。

4再挖一层:客户留言到 PII

接口:bus.contentCheck 参数:标识 notesid、分页 → 返回该员工收到的客户留言:客户标识、留言内容、时间、评分

前几处泄员工内部数据,这处直接甩到外部客户 × 员工关联数据。员工×客户可枚举,就不是“读一条”,而是系统性 PII 泄露面。

5枚举门槛:系统还白送“预言机”

填无效工号,服务端直接回“人员不存在”。这就是枚举预言机——系统替你标好工号对错,枚举成本直接降到零,不用自己撞。

6闭环验证:写 + 读互相印证

关键一步:走“写操作 → 用读接口查回 → 前后一致”。代签退后,用考勤读取接口查到这条记录的签退时间被真实更新——未授权写入能被查回,完整闭环。写、读、还有“系统帮你枚举”,三件事串起来,链彻底合拢。

要点:判定“写”漏洞,严格走 基线 → 写入 → 查回 → 还原。只写查不回,可能是假接口;能查回前后一致,才算成立。

04

定性:为什么撑得起“严重”

定级看三点:触达难度、破坏属性、影响范围

触达难度:不用登录、不用任何会话,一次裸 POST — 难度归零;

破坏属性:同时具备机密性(考勤/留言泄露)与完整性(代打卡/改签名)破坏;

影响范围:写 + 读全通,枚举即可铺满员工与客户。

三者叠加,严重(Critical)当之无愧。定级的标准是“攻击者要具备什么、能造成什么、能摊多开”,不是“是不是高危技术”。

05

根因与修复

根因,就三件事:

一、网关不鉴权:业务接口任何请求均可匿名调用;

二、身份凭据放前端:通行值写死在客户端 JS,全接口共用、人人可见;

三、服务端不做归属校验:工号、标识全由客户端传,写操作也无二次确认。

三条单看都平常,叠起来就是“匿名 = 全权”

修复,三步补闸:

一、网关统一会话认证,先建身份层、禁止匿名;

二、凭据服务端签发,绑定设备与会话、有生命周期,绝不落前端文件;

三、写操作 + 归属 + 二次校验,涉 PII 接口强制登录 + 权限 + 审计。

06

挖这种“能写”的洞,规矩放最后

· 只在授权范围测,用自有测试标识,不碰真实他人数据;

· 最小样本枚举,一个连续段证明“影响存在”即可,绝不拉全量;

· 每条写入证明有效后立即还原并复核,不留脏数据;

· 上报讲根因、给修复方向,不给一键复现的“配方”。一次负责任的验证,抵得上一百次没头没脑的重放。

最后说一句

整条链最值得琢磨的不是“怎么打”,而是那个被忽略的细节:那把钥匙,就明晃晃写在客户端里。可凡是给到前端的,都等于公之于众。

安全里有条朴素的道理——信任往服务端收,别往前端放。能从「读 JS」一路挖到「代打卡」,靠的正是这句话。

合规、克制、把思路讲清楚,比炫技重要得多了。

本文为企业 SRC 测试的实例复盘与思路教学。单位、域名、真实工号及接口凭证值均已脱敏,接口端点保留作讲解对象,内容不含可直接利用的攻击配方。


免责声明:

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

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

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

本文转载自:学点安全吃早餐 《替别人打卡之前,我先看穿它藏在前端的那把钥匙》

评论:0   参与:  0