提到安全开发头头是道,真到开发的时候抓瞎了。身为一个从预研到开发的程序工程师,我来简单说说我所认识到的安全开发。由于我是单纯从开发干起,很多东西都是(我自己总结的)从开发的角度来谈的,因此难免有局限性。这个我本来是 append 到了 TLS 自动机研发, 但是想了想也可以摘出来,所以又发了一次。
1.1 安全开发流程初期
安全开发名字高大上,但是实际上是个苦差事,因为安全并不是水桶,而是一个气球:哪里扎破一个洞,立刻整个就崩了。因此初期把握好安全开发就很重要,我比较喜欢从下面几个方面来分析:
- 目的是提供一款什么样子国外服务器的安全产品?是提供端到端的加密?认证服务不可抵赖?秘钥管理?权限管理?安全监测?每种不同的属性对应着不同的功能。project leader 还常常需要进行产品的横向对比,从而能够保证功能的灵活性和创造性。
- 需要保护哪些敏感信息,等级分为几种?比方说身份信息,权限信息,支付信息,爱好信息等等方面都可以被划归为敏感信息。
- 可能遭受哪些攻击?相比上两种,这个问题是最具体的攻击,常见的攻击很多种:供应链攻击,SQL 注入
- 可以复用哪些已有的安全工具和代码块?不要老去造轮子,要学会组合而不是创造。
上面几个问题实际上是安全开发当中大的目标,分析好上面几个问题之后,最大的问题就来了,怎么落地?说起来也不难:
- 第一步 培训:培训的目的包含三个方面:使得每个参与者(不限于开发者,测试者,经理,审计....)了解产品提供的安全属性,安全准则和具体功能,尤其是要对产品经理培训使得其明白安全不是个绝对概念,是有选择倾向的,总要做出抉择;对每个参与进来的开发者培训,使得其清楚常见的安全知识,比方说对称加密的安全性由秘钥保证,hash 不是加密,什么方法提供认证功能等基础知识;对核心开发者明确产品的核心逻辑和模块的设计(不一定是高速开发者,而是让核心开发者设计),必须达成对功能和安全的共识!我们在做 TLS 自动机的时候核心就三个人,每个人都可以相互替换对面的功能,TLS1.3 新功能 REUSE 和 0-RTT 的核心逻辑也是我设计完了,争论了几次才确定的,我们的测试完全参与不到我们的培训里,因为听不懂。。。
- 第二步 需求和功能划分:确定需求是个很有趣,却不困难的工作。因为核心逻辑是围绕关键信息的,所以基本确定了敏感信息和核心逻辑之后,需求划分就比较简单了。但功能划分是个很麻烦的事情,一方面核心逻辑可能并不复杂,但是边界错误和细枝末节可能会出现大量问题,因此每个细微的工程都需要有人把关;另一方面,安全开发产品有很强的连续性,安全经常是成环的,因此要确保具体的代码开发者是了解开发的模块的输入 /输出 /隐喻 /保障的,因此需要保证开发者是真的懂怎么回事,而不是似是而非模棱两可。这里注意,划分功能意味着划分责任,有的开发爱甩锅,有的 QA 爱甩锅,这时候就看 project leader 的功力了。
- 第三步 颁发安全准则:培训了,需求确定了,功能划分了,到了写代码的时候新的问题就来了,怎么保证代码是安全的呢?针对 TLS 可以看我写过 TLS 三理念,更具体的一般是:第三方安全性,很多安全问题是由第三方安全保证的,开发工程师精力不够,找 QA 啊;函数安全;工具安全。
多赘述一点东西:安全属性不是隔离的,端到端加密是很多功能的保证,但是奥卡姆的剃刀原则务必不要忘记,如无必要勿增实体,不要把其他层的东西放到本层来做!
1.2 安全开发流程中
安全开发流程中期实际上是个工程师埋头干活,抬头开会报进度的流程,这阶段的关注点在于 project leader 上。project leader 不但要对项目进度做好把握还要把握好需求变更的问题。project leader 还需要检查行为变化,细化安全规范。这就需要 project leader 能够明确安全的行为,并且能够根据具体的功能黑盒灵活的改变行为。
坦白讲,做 TLS 自动机研发的时候,虽然复用和 0-RTT 是我负责,但是关于排期这事我没咋催,主力是我,小功能分出去的时候我会提前培训开发的同事;每天问问进度和问题;明确行为规范。所以没啥排期的变更,行为这块一开始三个核心争了很久,也很确定,所以没遇到啥大问题。
1.3 安全开发流程后期
安全开发流程后期实际上主要的关注点不再开发工程师上了,在于 QA 和运营人员:运营人员要执行静态检测和动态监测; QA 要执行模糊测试,输入测试等多种功能,这都不是问题。问题在于:project leader 和开发者要在开发前期和开发后期以高度透明的角度,参与 QA 的测试 CASE 制定!换言之 QA 和开发必须都审核过测试 CASE,从而避免出现什么“现实不可能发生,测试不全面”的扯皮。
此外,需要记录开发过程当中遇到的实际问题和 BUG,并且将这些问题归类,加入到安全规范中。一方面能够给工程师提供具体的案例分析,另一方面能够很明确的细化规范和经验。实际上关于 0-RTT 的 DDOS 攻击我在分析 OPENSSL 的时候虽然想到了但是没明确,是后来 QA 参与进来我们才定性规定这是个问题的。
最后,最蛋疼的收尾工作来了:
- 如果出现问题,如何应对? project leader 需要根据具体的威胁制定针对补足方案,开发需要明确出现某种问题时,谁第一阶段参与,谁来参与追责。
- 如果在具体的安全规范出现问题,依据什么原则,听谁的?
- 开发和测试当中的资料归档在哪里?值得商榷的行为和安全保证的细节必须高度透明的写出来,并且能够被明确归档。
- 可复用的工具,代码和属性是哪些?哪些应当成为标准组件?这些(第三方,第一方)工具,代码安全吗?实际上这里我最直接想到的就是 HKDF-EXTRACT & HKDF-EXPAND,一个安全并且规范化的灵活伪随机码产生工具。实际上这个工作是需要一线开发工程师一起参与的。
1.4 遇到的安全开发中的问题
简单说说我们在开发过程当中遇到的一些实际问题:
- 人力不充足:人员短缺的问题很蛋疼,核心三人组是又订规范,又商量行为,光研究 RFC 就花了很久,更别提给其他人培训了。虽然能力增加了不少,但是确实很蛋疼。
- 需求的变更:我对需求变更实在是太烦了,小的需求比方说拓展的支持还好说,解析的时候多花点功夫即可。如果大的属性变了,那排期就得大变。
- 项目周期紧:这个对我们来说还好,虽然我们设计阶段功夫很多,但是设计好了我们的开发还是很快的。
结尾
实际上,从某种意义来说,安全开发是个文档>开发的过程,惊不惊喜,意不意外?