因为最近稍微闲下来一点了,所以重新开始发掘需求,然后就盯上了 CTF 平台。
一方面是因为自己目前还没遇到相对稳定且通用的 CTF 平台,另一方面也是觉得 CTF 平台是一个很好的学习机会。因为CTF平台需要处理诸如高并发、竞争、流控等问题,当中涉及到不少我未曾接触的技术问题。
即同一道题,不同用户解题后能获得不同的 flag
2021年hctf-game比赛所使用的平台在验证用户提交的 flag 的有效性上花费了较多的时间(随着越来越多的含有动态 flag 的题加入平台),导致不得不在反馈的及时性上做出了一定的妥协,还引发了条件竞争问题,出现了利用脚本快速提交多次 flag 能够刷分的漏洞。
为了避免重蹈覆辙,我认为应当如下设计 flag 验证及积分统计的相关流程。
但如果仔细想一下这个业务的实现方式就会发现,当一个用户在 flag 的提交高峰期进行提交的话无法立即得出flag的有效性的结果,因此应当有两个 api 用来处理 flag 的提交问题。第一个接收 POST 请求,只要成功提交进入数据库即可返回,且应当提交记录的 id,也就是 1 中的记录 id
;第二个接收 GET 请求,用于后续获取提交的 flag 的验证状态(使用轮询或其他方式)。前端在显示的时候应当给“验证中”之类的提示即可。
即平台中可设置多个子比赛
这个业务功能倒相对容易实现,只需要专门新建一张表用于存储比赛信息即可。
普通用户可通过发起专门页面发起举办比赛的申请
鉴于这种申请表单只给平台方审查,一共也就一张表,因此并不需要做过多的设计,只需要实现简单的增删改查,平台管理员可在后台直接通过或拒绝申请即可。
支持分页+分栏目即可
感觉主要还是前端的活,后端这边用表来存一下比赛的题目的栏目分级,大概画个树之类的吧。
这个就是上面支持申请举行比赛的扩充即可。
前端:
后端:
为优化 flag 有效性的计算速度,可以考虑使用 redis 进行一定的缓存。有几种缓存方案:缓存用户已提交flag的有效性、缓存有效的flag。在这个专案中,我认为为降低资源占用,仅用布隆过滤或布谷鸟过滤器将非正确flag进行一个筛是较优的解。
本专案中提出的排名、积分更新算法能够省去大量的锁,就目前所需的功能来看,只需要 MySQL 的锁就能 cover 绝大部分需求了。