Posts List

GShark-监测你的 Github 敏感信息泄露

近几年由于 Github 信息泄露导致的信息安全事件屡见不鲜,且规模越来越大。就前段时间华住集团旗下酒店开房记录疑似泄露,涉及近5亿个人信息。后面调查发现疑似是华住的程序员在 Github 上上传的 CMS 项目中包含了华住敏感的服务器及数据库信息,被黑客利用导致信息泄露(这次背锅的还是程序猿)。 起源 对于大型 IT 公司或者其他行业,这种事件发生的概率实在是太常见了,只不过看影响的范围。现在大家看到的,也仅仅只是传播出来的而已。企业没办法保证所有人都能够遵守规定不要将敏感信息上传到 Github,尤其是对于那种特别依赖于外包的甲方企业,而甲方的开发人员也是一无所知,这种事件发生也就是司空见惯了。 废话说了一大通(可能是最近看安全大佬的文章看多了),终于要介绍一下我的这个项目,GShark。这个工具主要是基于 golang 实现,这也是第一次学习 golang 的项目,结合 go-macron Web 框架实现的一个系统。其实最初我是看到小米安全开源的 x-patrol 项目。网上这种扫描 Github 敏感信息的工具多如皮毛,我看过那种 star 数上千的项目,感觉实现方式也没有很好。因为说到底,大家都是通过 Github 提供的 API 结合相应的关键字来进行搜索的。但是,x-patrol 的这种实现方式我觉得是比较合理的,通过爬虫爬取信息,并对结果进行审核。所以,最初我是一个 x-patrol 的使用者。使用过程中,也遇到过一些问题,因为这个库似乎就是小米的某个固定的人维护的,文档写的不是特别清晰。中间我有提过 PR,但都被直接拒绝掉了。后来,我就想基于 x-patrol 来实现一套自己的系统,这也就是 GShark 的来由了。目前,这个项目与 x-patrol 已经有着很大的变化,比如移除了本地代码的检测,因为这个场景没有需求,其实我本身自己也实现了一个基于 lucene 的敏感信息检索工具。另外,将前端代码进行了梳理,并使用模板引擎来做模板的嵌套使用。基于 casbin实现基于角色的权限控制等等。 原理 讲完了起源,接着讲一讲这个系统的原理。基本上,这类工具都是首先会在 Github 申请相应的 token 来实现,接着通过相应的 API 来进行爬取。本项目主要是基于 Google 的 go-github。这个 API 使用起来还是比较方便的。通过这个 API 我们可实现在 Github 来进行搜索,其实这基本上等同于 Advanced Search。因为 API 提供的搜索能力肯定就是 Github 本身所具有的搜索能力。最基本的包括关键及,以及一些 owner 信息以及 star 数等等。

如何做一个完美的页码跳转

需求 想给系统实现一个选择不同页面的功能,一开始的代码逻辑比较混乱,后来抽象出来就比较清楚了。第一步,咱们先说需求: 问题定义 我们希望实现一个页面切换,每次显示的可选的页码长度都是固定的,比如从第 1 页到第 11 页,从 21 页 到 31 页。这样能够实现一个统一的切换效果,可能还需要考虑一些边界情况。现在,我们令总页码数为 pages,当前选择的页码为 p,p 往左走或者往右走的步长是固定的,令步长为 step。那么我们现在要做的事情可以这么理解,我们要从 1 到 pages 之间截取可用的页码数,假设开始页码为 startIndex,结束页码为 endIndex。抽象一下,我们可以总结出以下几种情况: Condition1 startIndex < 1 && endIndex <= pages Condition2 startIndex >= 1 && endIndex > pages Condition3 startIndex < 1 && endIndex > pages Condition4 startIndex >= 1 && endIndex <= pages 这样抽象成四种情况,这样就比较容易理解。以线段的方式来理解,则是从 1 到 pages 截取页码。 代码实现 Show me the code. func GetPageList(p, step, pages int) ([]int) { pageList := make([]int, 0) startIndex := p - step endIndex := p + step if startIndex < 1 && endIndex <= pages { startIndex = 1 endIndex = startIndex + 2 * step } else if startIndex >= 1 && endIndex > pages { endIndex = pages startIndex = pages - 2 * step } else if startIndex < 1 && endIndex > pages { startIndex = 1 endIndex = pages } // handle some special cases if startIndex < 1 { startIndex = 1 } if endIndex > pages { endIndex = pages } for i := startIndex; i <= endIndex; i++ { pageList = append(pageList, i) } return pageList } 结语 没有思考清楚的时候,你的逻辑是混乱的,写出来的代码也是混乱的。所以先整理好思路,想好应该怎么写,可以画画图,理理思路,这样写出的代码既有逻辑出现 bug 的概率也会大大降低。另外一点,很多人觉得写业务和算法可能就相去甚远,都有时候认真想想,或许你的业务代码也可以抽象成一个小算法。