关于安全:CIS-2021网络安全创新大会代码安全体系建设实录

37次阅读

共计 9177 个字符,预计需要花费 23 分钟才能阅读完成。

一、背景

汤青松,北京趣加科技有限公司 平安工程师,实体书《PHP WEB 平安开发实战》作者,善于企业平安建设,SDL 平安建设。
PHPCon 2020 第八届 PHP 开发者大会分享《PHP 平安编码标准与审查》,NSC 2019 第七届中国网络安全大会分享《PHP 反序列化破绽剖析实际》看雪 2018 平安开发者峰会负责 Web 平安训练营 讲师

大家好,非常高兴给大家分享《代码平安体系建设》议题,我是汤青松,目前在 SDL 方面做的比拟多的。明天讲的这个话题其实和 SDL 有很大关系的。我这次分享这个话题的其实就是 SDL 当中的一部分。很多同学如果在甲方也会去做 SDL 当中的一些工作,所以我心愿我这次分享的内容对大家有所帮忙。

这次分享的话题是 SDL 当中的一部分,然而它不齐全是 SDL 因为我次要还是聚焦于在平安向左移的这样一个概念当中。所以明天分享的话题次要是聚焦于这个代码风险管理。那在这个代码平安当中可能有哪些危险点了?那它可能会蕴含技术方面的工作和非技术方面的工作,比如说管理工作以及这个学习方面的一些事件都会有解说到。

1.1 内容概要

我明天讲的这个话题,次要还是在于意识、技术、监督和学习四个方面怎么去发展咱们的平安工作?这里我做了一张脑图,那在脑图当中,我感觉从这个淡淡平安体系当中,咱们有四个层面了能够去做的,比如说这个平安培训。

在平安培训当中,咱们第一点要通知他有哪些危险点,第二个就是咱们得教他怎么去避坑,那么教他避坑了,咱们就能够间接拿到他这个仓库的代码,而后咱们本人先去剖析一遍,剖析完之后,而后在培训的时候咱们就能够通知他你这个代码了哪里会存在一些危险点,把这个问题通知他。

第三个就是咱们通知你了,你不能怎么去写,你应该怎么去写。那么咱们制订完这一套规定了,咱们不可能说其实人工去盯着您得有一套监督机制。这里我也会给大家去讲一下,怎么去联合 semgrep 和 GitLab 做一个钩子事件,实时检测这个代码当中的一些危险点。

那么第四个就是咱们在上线前必定会有平安测试。在平安测试当中可能会有哪些疑难点?那明天我大抵会提到这样几个问题点。那首先咱们来说一下平安培训咱们怎么去做。那平安培训我置信很多做技术的同学,他可能就是本人的技术了是比拟好的,然而让他去给他人讲怎么去踩坑以及一些案例,她不肯定是他善于的。

咱们先来说一下我是如何了解保障整个利用平安的,我认为它不是由某一个维度是否做得足够好来掂量,它是一个综合的方面。也是多个团队配合起来的一个工作,咱们作为平安人员在这里要负次要责任。

咱们要想尽一切办法去和开发和测试一起保障保障利用平安。咱们首先给这些开发人员建设这样一个安全意识,那通知他了互联网当中会有很多的一些破绽,那这些破绽了有哪些危害?那首先在他开发的时候,他就会想到不能让这个利用有破绽。

第二个让他无意识之后,要教他怎么去避开这些坑,不要让他晓得有这些平安危险起来,他不晓得怎么去解决,而后还是踩坑了。那么这个时候咱们平安人员本人在这个技术方面了,要有肯定的这个能力。

第三个在监督层面。如果说你通知开发人员互联网当中有很多破绽,也教他去避坑了。然而没有监督很多人了他可能并不一定依照你的要求去做,所以这个时候您得有肯定的监督机制。

第四点是是通过事件驱动,我置信作为甲方,你必定还会遇到一些安全事件去驱动。比如说咱们公司是做游戏的,还时不时会有一些拖机挂或者等等一些外挂这些方面的问题。那么咱们会把这些事件给整顿起来,整顿成案例,再给这些开发人员去学习。

二、平安培训

所以这里我讲几个非技术性的一个话题,就是咱们怎么去给这些开发做培训。那首先我感觉做培训有这几个方面,我能够给大家一些参考意见。比如说首次的这个培训咱们讲什么话题?怎么防止一次性把这个话讲了,那么我下个季度还讲不讲?是不是我一次性了就把话讲完了我感觉都是有一些技巧的,就是你第一次该讲什么货色。

第二个说咱们培训了是,一次培训了,咱们就把所有的这个开发组成员了都叫上。那么比如说几十号人,上百人都叫上,而后咱们本人在一个舞台下来讲还是这个小组去讲了。那这里头我是举荐大家小组讲,那一会我会讲到为什么去小组讲。

第三个就是案例就地取材案例了,咱们肯定要在每次培训之前把他那个代码关上去看一下,拿着他的代码给她们做一完培训。而后接着了咱们就发展咱们这次要培训的一个话题,那这样的一个模式。

2.1 首次根底培训

首次根底培训了咱们能够给他讲哪些货色了?我感觉你首先能够给他讲一下你在这个甲方平安当中了,你是怎么去给他们做代码审计的,你是怎么去做平安的?这个其实是她比较关心的,让他理解你的工作。那你平时会关注哪些点,你给他充沛交换一下。那么建设一个互信机制。

第二个你能够给他讲一下这个破绽分类,比如说了通用的一个编码型破绽,比如说 SQL 注入,XSS csrf 文件上传,而后命令执行代码注入等等这些问题。那把这些问题了给讲完之后了,咱们还能够给他介绍一下这个逻辑性破绽,比如说这个领取破绽、越全破绽、验证码破绽、短信破绽等等这些破绽了,咱们能够给他科普一下。

那么讲这些破绽的时候,你能够去联合他们这个小组了,他们是做哪方面业务的?比如说做中台的了,他可能会脱离业务。他可能没有这样一个领取的问题,或者说没有用户的一些问或等等和他这个主无关的一些问题,能够给大略提一下,但不要讲细了。

第三个你能够给他讲一下代码自查的一些办法,你能够教他一些简略的办法,比如说他写完代码之后了,怎么去审计本人的平安问题?但这个参数有没有做过滤类型,是否强制的,比如说我要介绍一个 ID 那在 PHP 语言当中了,那可能他没有应用这个整型转换,那么承受了有可能这个字符,那么拼接到这个 SQL 注入当中了对吧?那这个时候你就要跟他讲,你说你在这个接管的时候你得做一次过滤,你如果没有做过滤了,在拼接社会语句的时候你得做 pdo,而后查 SQL 大抵教他一下怎么去查。

那这个 SQL 破绽怎么查了?我置信做甲方的技术同学都有肯定的见解,在这里我就不开展了,你能够给这些开发的大略提一下。一般来说就是做开发的同学了。本人对这一块也是比拟理解的,你给他点个结尾,他本人很多事件他能想明确的。

2.2 小组培训

第二个就要在做培训的时候了,我的倡议是小组培训,比如说你们一个公司可能会分为很多个小组。那么我目前来说我次要是给后端的同学做培训。所以我个别做培训的时候我会讲后端的一些货色。那么后端他每一个组了他其实波及的货色都不一样,比如说有些组了他不会用到 HTTP 协定,他就会用这个 socket TCP 这种协定。那么你给他去讲一些 web 业务的一些破绽了,他可能不爱听。

所以做小组培训的目标了,我感觉次要就是因材施教。那每个组他有本人不同的一些特点,你得给他讲他本人不同的。那么你尽量在每次培训的时候,你尽量管制在 10 集体以内。而且我感觉工夫你要管制一下,就要管制在这个 45 分钟以内。们平时上课了对吧,也是 45 分钟以内。

说了你要有这个工夫的一个意识,你不要始终讲,讲完之后翻其他人压根就没来听,你要有以这样一个互动机制。那这里有三点了,我须要给大家去说的。就第一个了就是开始讲到了,你肯定要贴近这个团队的一个实在代码。你每次给他做培训的时候了,你得先把她代码审计一遍,审计完了多多少少可能会有一些平安问题,或者说有些不标准的问题。你拿着这个代码去跟他说,你不要间接上来,对案例那样不是不好的,很多人可能就不乐意听。那么第二个就是要贴近他的业务场景,方才也讲到了,那做 TCP 的你给他讲 HTTP 他不乐意听他,我压根就没有这个业务,你给我讲啥呢?第三个就是多分享故事的一个模式去造成一个互动的氛围。比如说你在给他做培训的时候,你给他讲越全的时候,那你就讲以前了,可能你挖过某个网站的一个预存破绽,你是怎么发现的,以及你可能在网上了看到过他人的一些案例,那这些剖析步骤了你能够给他讲一下。

你比如说我发现了这样一个 URL 的 ID 等于 100,那么我感觉想试一下,我把这个 100 了改成 101 在 URL 地址栏当中回车一下。发现看到了他人的一个信息,也发现了他人订单信息,发现了他人的一个个人用户信息以及其余的一些权限信息,多以这种故事的模式给他去交换,我感觉是成果十分不错的。

2.3 案例就地取材

第三个就是案例就地取材。那很多时候咱们给 A 组的同学去做这个分享的时候了,那他不肯定了有他们这个组的一个破绽案例。这个时候我感觉你肯定是就近的,你能够讲他们部门的对吧,能够给他讲这个整个公司的。而后这个案例就是尽量凑近他们这个团队。那么你怎么取这些案例呢?咱们晓得在 2016 年以前,这些互联网当中有很多这种破绽案例,包含各个大公司的一些破绽案例都是有的。但在 2016 年 6 月 1 号之后,咱们基本上看不到了,为什么网络安全法进去了,所以很多这种比拟直观的破绽案例了,咱们当初没有方法,说很轻松的拿到了。这个时候了,你能够从三个渠道取了。

第一个说你在平时做代码审计的时候,你把这些案例了给存起来,截好图。而后把敏感信息的打个码。然而把意思大略说明确,把这些案例给整顿起来。第二个就是从平安测试当中,咱们每一次业务要上线了,必定会有一轮平安测试,把业务测试当中发现了一些问题点,也能够整顿起来,咱们是有一个案漏案例库的。第三个就是破绽事件了。那比如说一些通用型的一些破绽事件,像那个 2021 年年末的时候,是不是有个 logic4 的这样一个组件,我记得在快过年的前几天了,那个时候出了一个命令执行的破绽,那影响范畴还蛮大的,那能够把这些事件了给它整顿一下。你能够通知他说你依赖了一些组件了,要及时降级。如果了你要援用一个组件了,你要最好查一下它的版本有没有破绽,有破绽的话你就不要应用了。

一般来说咱们 php 会用 composer , Java 会用另一个包管理器以及 Python 都会用包管理器,那么咱们要及时去更新一下,不要说咱们打包一次,几年咱们都不更新,那样很容易就会产生一个安全漏洞。

三、危险揭示

那接下来咱们要讲的就是危险实时揭示。那么咱们给他做完培训之后,咱们有这个首次培训,也有这个每个季度一次培训,也有这些案例的一些解说对吧,咱们还得有这个监督的一个作用,就是他们写完代码之后,咱们得及时去揭示他,以及了咱们每一个季度了咱们有一次全面扫描等等这些信息。

3.1 危险揭示的作用

那首先我讲一下这个危险揭示的一个作用,次要就是强化大家的一个揭示的意识。你不要讲了之后就不揭示了,过不了一周两周,他之前的代码习惯了,该怎么写还是怎么写?你会发现你之前的培训白讲了,你给他讲了之后了没有太大的扭转。所以你要有揭示。

那实时揭示了咱们能够在 git 的仓库当中做一个勾子事件,每一次它 push 代码的时候,咱们能够把他的代码了给拿进去,拿进去之后提取他改变的行,提取改变进去的行了。而后咱们来判断一下他有没有危险函数等一些问题。那如果有这些问题了,咱们就给他反馈一下,就通知他你哪个中央了可能会存在危险。

揭示这件事了有三点意义。第一个就是增强他的安全意识,让他晓得这个平安事件有人在管。第二个就是从源头当中去阻挡平安。但这个钩子你不要说遇到这个危险函数了,就间接给打回去。你能够在这个 git 当中给它返回一下,返回一个提示信息,通知它这个中央可能存在危险,让他去留神一下。比如说在命令执行这个中央你放了一个变量,那么你须要确保你的变量是可控的,是过滤了的给他这样一个提醒作用。

第三个就是晋升一下平安的反馈速度。那如果说你没有这样一个实时的揭示了,你每个两周去给他这个仓库全面扫描一次,那可能他代码都上线了对吧?

3.2 危险函数揭示

危险函数我简略列了几个函数,比如说这里了有这个代码注入的,有这个执行零碎的命令的,有应用这个明文 FTP 下传文件的,

还有一些加密库以及一些正则库,那这边还有一些信息泄露的揭示。

你都能够放到你的这个平安危险揭示外面去。我感觉优先级了,你能够把这些高危的了给大家放进去。比方像 FTP 的,你能够看状况,你放不放都行。那像 pprof 了,我感觉你必定得留神。那 PP info 外面还是有蛮重要的信息的以及 Golang 外面的,它间接应用了裸写了这个语句以及读取文件内容以及执行系统命令的这些危险函数了,你都给它去揭示一下。

3.3 钩子应用

那方才说的这个勾子事件了怎么去应用了?那其实这个勾子的原理次要就是在这个 git 服务器当中了,寄存一个勾子的这这个脚本,每次他 push 的时候了,服务器他会触发这样一个脚本。


触发脚本的时候,你就能够通过一些命令行了,你去获取到他有哪几个文件有改变,那改变了一些行号了,你都能拿到。完了这些数据之后了,你把这个检测的规定就方才我提供的一些危险函数,以及你本人去拓展一些,把这个规定文件给它写好。

第二个,这个 semgrep 当初曾经比拟风行了,曾经有很多这个团队在应用了,所以我感觉也是一个比拟成熟的货色,你能够通过 sum group 加上这个规定去检测这个代码,而后把这些危险给返回回来。那么具体的实现地址了,我之前写了一篇文章,还是比拟具体的,那大家能够去关上,而后依照操作了去实现就行了。

那这里我给大家展现一下这个钩子了,它会是一样一个什么样成果?比如说我在命令行当中,我输出了一个 git commit 而后提交这个代码,而后在推送的时候它就会触发。那么在推送的时候,咱们能够看到他这边通知我哪个文件。那么它的行号,当中有个 EXEC 执行了这个 git 当中的 A 这个变量,那么它有可能会导致一个命令注入,那肯定要确保内容不是用户随便管制的。那么这样一个提示性的话语,那具体了你能够去把这个界面了给它优化一下也能够。

三、代码审计

在代码审计当中咱们也有四点能够给大家去分享一下的。


那首先咱们代码审计的方向,咱们要怎么去审计呢?那这里就有一些偏技术型的话题了。那么有一句话叫文无第一,武无第二,置信做技术了也一样。

3.1 代码审计方向

那么第一个就是通用编码型这这个审计。那比如说咱们能够审计这些这个 sql 注入、XSS、命令执行、文件上传等等这些,那么咱们能够通过通用型编码降级进去。那么第二个咱们得联合她的业务去审计。那比如说你只有有用户的零碎,你才有这样一个用户密码找回以及一些权限方面的一些破绽。

第三个就是组件型的一个,那你要依据这个仓库所应用的语言,比如说 php 的,那用 compose,那 Java 的了,那用另外一种模式。那么把这些组件了,确定一下它应用的这个组件版本,而后来确定他是不是有几个组件破绽。那具体了通用型编码审计办法了。后面其实我也简略提了一下,其实次要从这三个方面去看吧。


第一个就是接管参数,如果说我这个中央接管了一个 ID 我明确晓得它是一个整形的。当我接管的时候了,我没有用整形去强制接管。那在这种弱类型语言比如说 php 外面比拟常见,那么你就能够去追踪一下这个变量,有没有放到 sql 语句外面去执行,有没有去返回到这个前台,有没有可能放到这个命令执行外面放在这个代码执行外面等等。这些形式就是追踪接管的参数,它没有过滤,咱们就始终追到底,始终到这个程序完结。那么这是一种形式。

那么第二种形式就是关联词反常。关联词反常了次要说咱们能够去这些函数的中央看一下它外面放的是不是变量,如果放的是变量,咱们就追踪这个变量的起源。那如果说这个变量是接管用户的,并且没有做过滤,而后放到这个危险函数外面来,那么肯定是有平安问题的对吧?第三个就是咱们去解析它的依赖文件。那么目前来说就是 PhP 了,Java Python 以及 go 它都有依赖包治理。所以咱们当初去检测它的依赖其实是比拟好实现的,咱们这里都能够去做一个。当然有一些它可能还是比拟传统的形式。比如说 PhP 在老版本了,在 PhP 7.0 以下了很多这个零碎了,他并不会应用 composer 他间接把这个源码了间接下载到他的这个目录下。那这个时候你解析可能会比拟麻烦。

3.2 工具选型

那么这个时候呢您得借助一些第三方的一些工具去剖析进去。说到这个代码审计的一些工具选型了,目前前这些我大部分都用过,比如说 fortify,用的是比拟纯熟的。那么 check max 了这一款工具了,我还没用,因为还没有买他们的第三款这个代码卫士的话是那个奇安信的。那这一款我倒是用过一段时间。

第四个了,我目前用的是比拟多的,次要是用在这个钩子检测当中。审计零碎当中也用到了它的一些性能,但目前来说就是全量代码审计了,我还是比拟喜爱用这个 fortify。那么在这个钩子事件的时候喽,因为 fortify 带它是那个 AST 的这种语法分析,它会比拟吃内存,而且反应速度比较慢,所以目前次要还是依赖与这个 Sem group 那么第五款这个 CodeQl 的 CodeQl 了这款工具了我前段时间还在理解,还没有用到这个生产环境当中,所以我也不太好说。

第六款工具了目前来说我用过。的感触就是它是一个齐全开源的,包含他的这个规定,包含他的这个引擎零碎大家都开源了,但他只能目前来说能检测 PhP 其余的后端语他不能检测。所以目前我用的这个 fortify 和 Sem group 比拟多一些。fortify 就是要商业的和 check max,其实代码卫生也是商业的。fortify 我目前来说还比拟好用,checkmax 没用过,没有太多发言权。

这个 fortify 泛了我用过一段时间,去年十二月的时候。用过一个月。次要的感触就是它和福利范检测进去破绽数量是比拟类似的,但它的界面设计了点击起来我感觉很不顺畅。据说这个往年 3 月份会有一个新版本,到时候大家也能够去试用一下他们的 SemGroup , 他的规定是 开源的。而后它的这个引擎了它是加密的。

第五个了 CodeQL 了。那 github 当中就曾经大规模应用,当然也能够去体验一下。然而你只能用于学习,不能用于商用。那当初我再来说一下就是批量代码审计的一个实现形式。那目前就是几款产品,其实它对单个单款库的反对都还比拟好。我在做甲方的时候会遇到这样一个问题,那因为我是要对整个公司的代码库的安全性了负责的,所以我不能说就检测几个仓库的一些平安问题点。那时候我得批量去审计。那像咱们公司可能有 600 多个仓库,一个一个关上,我得疯掉,像 fortify 关上一个仓库大的我的项目,它可能得一两天。光审计起来可能得花个一年工夫就让他剖析完。所以如果用这种默认计划其实不是太事实的。

3.3 批量代码审计工具

所以我写了一个批量代码审计的一个工具,就是 QingScan。那么它次要的作用它其实是蕴含了四局部,一部分就是信息收集,第二部就黑盒检测,第三局部就是代码审计。那还有一个专项利用。那这里我次要提一下它这个白盒审计。那白货审计它其实次要的目标就是把你的这个我的项目了给拉下来,而后调用这个 fortify 以及这个 sem group 还有其余的一些代码审计的一些工具了,对它进行一一扫描。那么扫描完这个,而后接着就扫描下一个。那么也能够分布式部署。那目前来说我曾经在咱们公司应用起来了,也举荐给大家去试用一下,那么这个地址在这里

https://github.com/78778443/Q…

四、平安测试

再就给大家分享一个平安测试当中,平安测试次要有这几个,web 站点测试、API 接口测试、公有协定测试和案例输入。

4.1 web 站点测试

那这个 web 站点测试了其实我感觉还是比拟惯例的,目前也没有什么太大的一个技术难点

比如说测试个 sql 注入、XSS 但个别目前来说是个 sql 注入和 XSS 这些问题点曾经比拟少了,XSS 可能是反射型 XSS 多一些,然而影响我感觉也不是太别大,因为当初都是那个 cookie 加密的就是 HTTP Only 另外这种模式,所以没有太多可说的。

4.2 API 接口测试

API 接口怎么测试了?API 接口它和这个 web 站点它有一些区别。像 web 站点咱们可能能够通过爬虫的形式把那地址都爬虫进去,而后再对这个地址进行扫描。那扫描有后果了,咱们就把这个验证一下,验证完之后而后提出来。

那么 API 接口有个问题点,就是咱们没方法去爬虫。所以这个时候了咱们通常关上一个 xray 的一个端口,用这个服务模式。而后手机了咱们把这个端口指向 xray 的这个代理地址,而后咱们去关上一些申请,把这些地址收集起来,而后去扫描。同时咱们还会有一个 URL 地址的清单,就是这个地址其实是开发那边给咱们提供的。而后这个功能测试那边同学也有一份咱们在对这个地址了去进行这个逻辑进行的一个测试,比如说越权以及这个领取破绽等等这些方面的问题的检测。

4.3 公有协定测试难点

第三个就是公有协定测试,那公有协定了其实测试起来是比拟麻烦的,比如说这个 socket 的协定,那么 TCP 协定,那么咱们其实是没有方法间接把这个数据包了给解析进去的,除非了咱们得有一个模仿他们的客户端。那目前来说只有几个就是重点项目了,咱们会和他们对一下这个端和服务端的数据的一个格局,而后进行模仿测试。那这个工作量还是蛮大的。所以这个公有协定了,看各位的这个人手够不够了,没有太多好办法,只能去模仿这样一个这个公有协定的客户端。

那传统的内部站点测进去是最简略的,无非就是先收集地址,而后测试一下惯例有没有问题点,而后对这个业务性能进行测试一下。那业务性能也就是说我越权领取,而后用户密码找回验证码等等。好 API 接口了。那次要就是咱们要把地址先拿到,拿到地址之后其实其余的测试方法都差不多。那么拿了这个地址了,咱们有两种形式。第一种说从开发团队那边间接拿到一份 API 该的一个列表,而后并且搞得分明他们每一个参数是做什么用的。而后对这些接口了去进行一些扫描测试以及一些逻辑性测试,和传统概念区别不大了。

第二个就是有可能咱们从开发团队那边拿了不全对吧。所以咱们能够用 reay 去关上一个端口,会应用这个 burp suite 关上一个端口。而后手机设置一下代理,把咱们的数据包了从那边通过一下,而后把这个地址也收集一批。第三个就是比拟麻烦了,方才也讲到了,没方法轻易理解这个数据包的格局,而后比拟麻烦。而且不好轻易去各做数据包,你必须通过程序的形式,你人工的是很没有方法去改数据的。但有些数据它就是这个十六进制的。那他不是说就是你看到的铭文说了你得模仿一个客户端,用于封装数据包。看你的这个人手够不够,人手不够的话,测了也没有太大意义。

4.4 案例输入

每次咱们检测出破绽,或者遇到应急响应事件能够将它录入到咱们的平安零碎中,不便咱们积攒教训

那这里有个图,就咱们这个团队了,对公司的一些破绽了一些整体状况。那有季度的一个报表,有这个部门的一个报表以及统计信息,就是它的破绽类别的一些统计信息。

五、总结

那明天次要就分享这四点内容,从这个培训到这样一个钩子的制作以及这个代码审计,那最初以及平安测试。那么这一次的话题就讲到这里了,那心愿对大家有所帮忙。再见。


作者:汤青松
微信:songboy8888
日期: 2022 年 3 月 15 日

正文完
 0