软件供应商攻防常规战之SDL

软件供应链的安全问题越演越烈,在近几年的国家级实战攻防演习中频频发生。即使是在常态化,我们也在不断地帮客户(被供应链攻击的上游客户)应急或在自家环境中发现过此类事件。因此企业在防守难度上,又新增了一块高地。

作为安全产品的供应商,在瞬息万变的攻防态势下,正努力、主动地试图摸索出一条解决之道,提升产品的自身安全性、以及到客户侧的整条链路安全性,以更好的服务客户。本系列文章将从供应商视角,介绍实战场景中遇到的软件供应链攻击,分享对应的常态化实践措施,以及在攻防演习前的大型集中战。

本章将介绍常规战的第一个举措- -SDL(开发安全),目标是发现和解决产品的安全漏洞问题。

01

历史文章回顾

曾于2019年写过《SDL最初实践》系列文章,回忆和整理了一些过往的从业经历,尤其记录在某支付公司做应用安全建设时、落地SDL的一些实践和经验。主要内容包括:

安全培训

安全需求

安全设计

安全开发

安全测试

安全审核

安全响应

正如总标题所述,的确是SDL的最初实践,属于初级产物。时隔5年回顾这些文章,有点生硬,就好比拿到一套武功秘籍只掌握了外的“行”,对于内在的“神”的理解不够深刻。此外,有的安全活动并没有在公司全面推广,有的安全活动也不够深入、仅停留在点到即止的水平,有的安全活动没有嵌入流程形成常态化,...总之,名副其实。不过,若是没有当年的实践,恐怕今天就看不出不足了。

02

实施关键要素

该部分是方法论层面的,其实与做其他事一脉相承。欲做好一个工程化的项目,需要组织、流程、规范和工具的支撑。在软件开发安全中,将这四方面融入之后为:

2.1.开发安全组织

在开发安全领域,通过建设组织架构可以解决三个核心问题:

  • 向上做资源申请:从公司战略拆解到产品安全部的职能上,有助于团队找到自我价值,因此向上的组织建设一定要想办法打通。另外对于后续安全活动的开展,也是需要上层安全组织进行决策和支持;
  • 团队内明确分工:一个健全的产品安全团队应该要有流程体系、安全工具、安全测试、技术运营四部分,每个小组聚焦解决职责范围内的工作内容。值得注意的是,在技术氛围强的团队中,流程体系建设可能会被冷落,此时TL要意识到其定位和价值。同时流程体系建设的同学也需要反思,在自己领域方面是否达到专家水平,还是安全测试工程师也能干出自己现在的成果?
  • BP机制助力落地:这是解决安全资源不够用的招儿,也是将软件的安全质量“还给”业务部门的可行方式。每个业务线负责自己的产品安全质量,这不是甩锅,因为只有业务自己重视了,安全才能做好。很多公司都在建安全BP,但建议要常态化运营,比如业务A的安全BP人员调岗或离职,需要有对应的流程来引导新的安全BP做培训、认证、上岗。尽可能的让BP感受到一种荣誉,比如在内部的IM上定制徽章头像,经过认证的BP就可以佩戴等。

2.2.开发安全流程

开发安全尽可能的不要新造流程,更不能新建一条独立于开发流程的流程,逼着业务方来使用的话,极大可能把自己给玩没了。比较合理又常见的做法是在现有开发流程中设置卡点,比如针对内部应用,在申请内部域名时检查安全测试是否开展以及通过情况;针对外部应用,在申请对外映射权限时进行检查。

如上图所示,所有的安全活动尽可能嵌入到流水线 ,尽可能做到自动化触发,不能自动化的集成到开发安全平台上做成工具集,由业务线自主使用工具进行安全扫描。

2.3.开发安全规范

这里并不是指编码安全规范,而是所有与开发安全相关的规范。若单独把开发安全作为一个域的话,一级规范就是《产品开发安全提测作业规范》,要求所有上线的系统都要经过安全测试、安全测试内容、安全测试通过要求、违规处罚措施等;下一级的规范有《网络安全事件管理办法》、《开源软件使用管理细则》,明确各团队对公司内开源软件的管理职责、要求各业务只能使用内部仓库提供的软/组件等;三级规范就是常见开发语言安全编码规范、安全基线等。

针对编码安全规范,关键点在于编写和应用。前者可以参考的内容非常多,各大公司对外发布的编码安全规范、OWASP安全编码指南...但不能盲目的抄这些最佳实践,一定要从自身实际出发(聚焦业务系统常见的安全问题,范围和高度又要往上提炼一层),不追求大而全,要的是有用干货。因此在我们的编码安全规范中,外部最佳实践的内容占比大概在20%-30%。另外需要注意编写的视角,因为是给开发看的,所以不要用纯安全视角来写,还要有充实的示例代码。

落地方面,培训-考试,有一定作用但不是效果最好的。只有将规范尽可能的落到SAST的检测规则中,在编码阶段进行检查,才能实现高效、有效的检查。

2.4.开发安全工具

安全工具的形态可能是一个checklist、问卷亦或是系统,下图列举了一些常见的开发安全工具类别,在成熟度非常高的环境中才会全部出现。然而这些工具不都是能够自动化嵌入到开发流程中(如CI/CD),即使塞到里面也基本上都是异步扫描,由于误报多、需要人工干预等问题,会阻断流水线,这是业务方不允许的。

常见的倒“8”字的DevSecOps工具链,比上面的更加齐全,咋眼一看可能觉得自动化程度较高。其实不然,鲜有人说了或说清楚工具的联动及实现方式。依我看来,联动触发扫描不难,但是要串入到流水线中并做门禁阻断,这挑战非常大,对安全检测工具的性能和准确率要求极高。

03

最佳安全活动

在Microsoft SDL中安全活动比较多,但各家在结合实际资源投入时,发现无法按照标版进行落地,必须进行剪裁。曾经也有不少人在咨询,想要做开发安全的话应该重点建设哪些安全活动?本着发现漏洞和隐患,为业务保驾护航的目标,对常见的安全测试总结了四个“最”:

3.1.最直接的DAST

站在安全性的角度讲,软件供应商比较担心的问题是:在客户现场被测试出有漏洞,而且还不太清楚怎么去改。约五年之前,客户侧检测软件的手段还主要是漏扫,即标题中提到的DAST。对供应商而言,则应该使用主流(或客户侧常见的)商业漏洞扫描工具,主动验证软件的安全质量。在现在看来,这便是最基础的安全要求。不少公司已经投入人力资源,关注供应商自身安全性的过程化管理及实现,以及对交付物进行渗透测试等方法进行验证。

3.2.最高产的SAST

调研并在内部建设好安全测试工具链后,发现漏洞最多的还是SAST,也最便于融入研发流程。虽然面临误报多、覆盖语言不全、编译扫描慢等问题,但也并非不能解决。比如:

  • 扫描结果误报高:SAST工具默认会集成安全和代码质量方面的检测规则,若是安全团队,则直接把代码质量相关规则关掉、不关心的漏洞类型关掉,这便是初始的规则集,然后再去持续加白优化。针对代码中的安全函数(一般会做加白),需要针对性的做对抗测试,即尝试bypass、找出漏洞利用的绕过姿势。另一个不错的思路就是关联编码安全规范,不在规范内的最开始可以关掉,于是就有了初始的规则集,然后再去根据发现的安全漏洞类型和特征,不断添加检测规则及处理误报。两者都可以落到自研和商业工具,不过后者更匹配自研场景。
  • 覆盖语言不完整:很多公司的技术栈并不统一,多个主流或少众的编程语言并存。在做工具选型或调研时,优先关注的基本都是公司主流语言。针对覆盖不了的情况,可以是找其他工具进行补位,即在自动化方案设计时要接受多个SAST工具并存的状态,甚至是引入人工审计作为补偿措施。从另一个角度来讲,异构的SAST工具集,也有助于发现更多的漏洞,不过维护成本会变高。
  • 编译扫描速度慢:从扫描原理来看,编译型的精度和准度会高于不编译。常见的开发语言Java、PHP、Go,可能会由于拉不到依赖而失败,故需要配管或安全人员处理。最令人头疼的是C/C++的编译过程,有的产品操作系统老旧如CentOS 5,编译环境非常落后,产线也不敢轻易改动,其失败率的处理和编译时间都会非常磨人。所以在效率和误报率之间需要根据双方的接受度,进行抉择。

3.3.最饱存质疑的IAST

交互式扫描具有高检出、低误报、嵌入研发流程影响小等优点,普遍被业内看好,一度认为是开发安全左移最适合的安全测试工具。不过从实际实践情况来看,插桩意味着对线上(测试环境)的应用有改动,推动覆盖率增加了一点难度,尤其是对灌装到硬件中的产品;误报方面,总体确实会比DAST减少,发现的漏洞数也会更多一些,但并不是厂商宣传的那么高。这里提供一组数据作为参考,曾使用某IAST自带的初始规则、对某个内部产品进行注入类测试,在已知的26个漏洞中检出10个,检出率为38.46%。在插桩部署方面,如果有比较好的研发流程和基础,IAST插桩自动化部署到测试环境检测,的确是一个不错的方法。

3.4.最费劲的人工测试

有余力,人工安全测试肯定是必不可少的,或者没有余力也要挑着做。因为SDL的工具集,并不能检出所有常见的风险和漏洞。比如:

  • 隐藏深的web漏洞:无论是SAST,还是IAST、DAST,总归有一些常见的web漏洞会被漏掉,这部分靠人工经验、单点手工测试能够发现一些;
  • 业务逻辑类的漏洞:常见的越权、跨越既定逻辑完成业务流程、短信/邮件炸弹、第三方服务恶意消费..这些都是业界(自动化)难题,与业务场景紧密相关,大多只能铺人测试;
  • 数据安全相关问题:在需求/设计阶段或许已有数据安全相关要求,但在后续的开发安全活动中很可能缺少这方面的技术验证,如前端显示敏感信息、API返回过多的敏感数据、多接口数据凑在一块造成的敏感信息泄露、密码复杂度要求存在缺陷...有的可以从流量层进行统一分析与检测,但其难度很大,并不适合于大多数公司,故更多的还是人工测试。

04

历年经验提炼

4.1.SDL不足以对抗真实的实战演习

从19年到23年,我们的SDL经历了从0-1的过程,尤其是从21年开始,每年都进行了一个大版本的迭代:把SAST、SCA嵌入开发流程并实现自动化触发扫描;IAST、DAST、CAST(自研的客户端静态检测工具)作为安全能力移交给业务方进行自检;所有工具统一化入口、所有工具的阈值和通过要求统一化管理;所有安全检测结果集中管理与分析...

从正向建设的指标来看,内部制定的两个开发安全指标(提测次数、次均漏洞--每次提测被安全部门发现的漏洞数)均有明显收敛和提升。但在这几年的国家级攻防演习中,每年均有0day漏洞被外部攻击队利用。从结果论的角度来评价,SDL是整体开发安全水位的治理,很难对抗攻击队针对某个产品的深度攻击。所以需要另辟蹊径,寻找对抗方案。

4.2.编码安全培训解决不了代码漏洞

这里的解决并不是要求90%或100%那么严苛,毕竟从“知道-做到-做好”十分艰难。当前的部分SDL安全活动由业务方主导,比如SAST的扫描结果需要仓库owner或相关干系人进行研判,他们也都认真去执行了,但却把真实存在的漏洞给标记为误报。进一步沟通之后,发现即使是参加过编码安全培训、想提升安全质量的开发,其思路也和安全不同,在他的眼里有的漏洞就是不存在风险。

为了解决这类问题,进一步采取了复盘的方式。业务线开发团队复现当时的判断逻辑,安全人员紧随其后指出判断逻辑中的问题点,剖析出误判的原因并总结沉淀。以此为开发安全培训素材,又通过技术分享和培训的方式反馈给更多的业务线。

4.3.安全培训效果最好的是学以致用

大家都在做安全培训,也都在绞尽脑汁的想培训效果评估模型or方法,但到头来还是出勤率、考试得分,真正起到的效果比较局限。为何不换个思维方式?让业务用起来,安全人员设计好“圈套”让业务转起来。比如在推行安全测试工具时,先在产品安全提测作业规范中做明确要求产线自检、然后对全公司发布,其次组织安全工具赋能培训,关注各业务线安全BP的出勤率,至于效果就让他们在日常的安全提测中验证吧。掌握了培训内容,就能快速完成自检;若是摸鱼,则会影响自身的业务发版。

4.4.产品安全蓝军是绝佳的补偿措施

建立产品安全蓝军的思路,实则是来源于企业安全蓝军,通过攻击检验安全建设的盲点及不足。我一直都认为:产品安全就是企业安全建设的缩影,原则、思路甚至面临的困难、存在的问题都是相通的。不过初始目的是:让产品安全蓝军走外部攻击队的路,让他们的路更加难走。即:想方设法打产品、拿权限,不仅要业务线提供外部攻击者可以接触到的物料,还要利用内部优势,给他们提供源代码、架构图及与开发进行必要的沟通。

从效果来看,23年对某个产品发起攻击,耗时一个多月但收获了100多个漏洞,大多通过组合利用能够拿到产品权限。在23年的演习前后,也少有从外部收到该产品的0 day。这更加坚信去年初的想法,产品安全蓝军模式能与攻击队对抗。

4.5.开发安全下一个高价值点是运营

SDL体系跑起来之后,建设阶段的指标正向引导的效果相对变小。一直在琢磨如何提升,下一阶段做什么?继续借鉴企业安全建设的思路,转向开发安全运营- -把SRC和蓝军及演习发现的产品漏洞作为输入,组织SDL的体系设计和工具运营人员进行复盘,挖掘不足进行整改。以下是将重点转向开发安全运营的几个标志:

关于更多开发安全运营的理解与感悟,将在后续的文章中专题介绍。

05

本章小结

综上所述,从实施关键、最佳活动、历年经验三方面,对SDL的建设进行了分享。SDL的建设是需要时间的,短期并不能出效果,需要持续不断地投入和迭代。希望对读者带来一些思考,能有些许帮助。