站在安全审计人员和客户的角度,如何更好开展审计工作?

撰文:Jean-Philippe Aumasson 与 Antony Vennard,前者为 Taurus Group 联合创始人,后者为 HexHive 研发工程师
翻译:卢江飞

我从事安全审计工作已有许多年时间,有时自己独立审计,有时和 Kudelski Security 合作,审查各种加密功能实现,从智能卡应用程序和专用芯片到 Web 和移动应用程序,从标准算法和椭圆曲线算法到共识协议和零知识证明。我也与许多不同客户一起合作,撰写了大量审计报告,当然也看过其他审计员撰写的报告(有利于我从其他角度看待问题)。总体来说,我了解审计过程中有哪些事情行之有效,也知道哪些事情劳而无功,许多经验教训如果能早点明白就好了!我很希望所有审计人员都能遵循一定质量和道德标准,也希望客户能更好地了解他们对审计师的预期和要求。因此,我将根据自己的从业经验分享一些工作准则,旨在让其他审计师做得更好、让客户获得更高价值(这些东西应该会比较适合你,但可能不会一直有效)。当然,我可以分享很多建议,也可以讲很多故事,或许在某个时候会写一篇更长的文章,但我「故意」总结几个最有益、最有价值的东西。

如果您正在进行加密项目审计,并对相关指南发表评论,请使用 GitHub Issues;如果你想提交自己的工作,请随时进行 Pull Request。正文开始之前,我想先感谢几位贡献者,他们是:安东尼·文纳德(@diagprov)、托马斯·珀金(Thomas Pornin)、还有安全审计机构 Trail of Bits。

duotone (1).png

对于审计人员

不要夸大严重性:有时,审计人员会把问题严重性评定为「高」,做出这样的评级决定有时并非因为项目真的有明显问题(通常意味着代码存在较为严重的漏洞),而是因为项目只是「看起来」很糟糕并且会让审计人员感到尴尬(例如,使用 MD5 信息摘要算法),或者因为他们推测在事件重合的情况下或许会出现漏洞,比如黑客真的猜到 256 位的密钥……但是客户并不关心您对 bug 的个人感觉,他们只需要有意义的风险等级,然后再去确定修复 bug 的优先级,这样才能(在适用时)与用户进行交互。如果漏洞确实非常严重,比如按照威胁模型的定义,这些漏洞很可能被利用,而且存在严重危害,那么可以将其评估为严重漏洞,但是,你需要清楚阐明漏洞的潜在利用场景和业务影响(比如数据丢失、DoS 等)。夸大严重性不会帮助您在审计工作中树立声誉。

具有建设性:你需要找到解决方案,而不是仅仅找到问题,发现的每个问题都需要提供一些附带的解决建议。你不能在重言式推荐中简单写一句「修复这个问题」,这样是不够的。相反,你要具体说明问题并在可能的情况下提供补丁。作为审计师,找出最佳解决方法(尤其是设计错误)并不总是那么容易,所以别犹豫!你可以尝试先写下几种解决策略,然后再与你的客户进行讨论。你还可以把解决方案做一个区分:

  • 短期修复,此类解决方案比较简单,例如添加其他的健全性检查或更新某些依赖性方案;
  • 长期修复,此类解决方案耗时较长,你需要做更多工作或进行系统 / 设计更改,例如应用程序接口(API)更改,使用不同的框架、或重新设计 CI / CD 管道。

灵活调整范围:在估算审计工作量的时候,几乎不可能做到设计一个「足够好的」工作人日预算。审核人员有时会使用各种启发式审计方法,例如每小时覆盖 N 行代码或编写代码所花费时间的 N 倍,但是与设计复杂性、代码清晰度、所用语言、审核人员对系统的熟悉程度等定性因素相比,这些定量苹果通常没有什么价值。最终,你会在范围内 20% 的代码行上花费 80%的时间,这种事情在审计开始之前很难预测。我发现有一个效果很好的方法,就是为客户提供一定范围的工作量上限(以免超出预算),只要我感觉完成了,就可以停止审核。

严格按照工作时间收费:这应该很明显,但这并不总是规则,特别是在规模较大和专业程度较低的公司中。 「一天」的工作通常被理解为相当于 8 个小时的工作,因此,你应该按每 8 小时工作的天数收费,而不是为分配给该项目的员工出现在办公室并工作了一个工作日的每个工作日收费。毕竟,有时候你需要在会议和茶歇之间耗费好几个小时。

记录你的工作:每工作 1 个小时或 2 到 4 个小时时间之后,你需要追踪一下自己的工作,包括已经分析的文件 / 功能 / 机制,然后记下你的想法、或是失败的攻击尝试。你可以把自己的工作想法与团队其他人进行共享,优势客户可能也会要求您证明自己到底在工作时间做了些什么,为了能够证明工作合理性,你需要记录自己的工作。

人多力量大:有时,你可以将代码审核任务按照代码库的不同组件进行划分,比如 package、subcrates 等,在团队成员之间分配工作是很自然的,但是这种方法的问题在于——某一个人只关注给定的代码行,而没有完全了解组件之间的交互。如果想做的更好,我发现其实可以让两个人负责审计同一组件,并且每个人至少要对所审查的所有组件以及它们如何协同工作有基本的了解。两个人工作也会有助于共同讨论识别错误和检测模型错误,而且不会让你感到无聊。

积极交流工作并提出问题:您需要与客户建立 Slack 或其他群聊(如果没有,请尝试创建一个),通常来说,最好在准备工作说明时、或是在启动会议期间能和对方就如何使用沟通渠道达成共识。我建议,审核人员需要定期共享他们的审计工作进度,比如自己正在评审代码中的哪一部分、发现哪些内容不清楚或有错误信息,同时还要在发现问题后立即报告,这将有助于你及早发现错误,并让开发人员实施 debug 措施。你需要毫不犹豫地询问开发人员是如何设计决策,并了解代码预期行为,这样才能更好地了解设计师 / 开发人员的观点,积极交流工作并提出问题也有助于您发现问题并制定更充分的解决措施。

撰写更好、更详尽的报告:详尽的报告好过于简洁的报告,对于一个熟悉攻击和利用技术安全漏洞的审核员来说,往往很想跳过一些细节问题,并期望读者自己填补漏洞描述和解决建议中的空白,但这样做的确有一定风险,因为读者优势会误解实际问题,继而无法正确解决。编写详细的报告信息还可以帮助你发现分析中的潜在错误或误解,同时你也可以充分利用外部资源,例如博客文章、研究文章、甚至来自类似项目的代码库。

坦白自己没有找到的内容:如果你的审计报告中没有涉及到任何一个安全问题,对于审核员和客户而言可能都会感到一丝尴尬,客户甚至会以为审核人员可能没有很好地完成工作,自己的钱也许白花了。为了减轻这种担忧,无论您的报告包含 0 个结果还是 100 个结果,最好可以首先列出自己一直在寻找的错误类型,然后还可以描述自己使用过哪些审计工具及其配置,并枚举已验证的属性(例如,椭圆曲线点验证、随机数唯一性、零知识属性等)。

永远不要将事情视为理所当然:在审查算法或协议实现时,请始终了解算法和协议期望实现的目的,然后可以创造性地思考可能出问题的地方——

  • 即使实施的方案已经证明有一定安全性;
  • 即使实施的方案已经具有全面的单元测试和完整的覆盖范围;
  • 即使实施的方案已被正式验证,甚至是用 Rust 编写的。

但是,安全问题依然可能来自于许多意想不到的方面,比如:

  • 程序员写代码时的一些怪癖;
  • 错误的处理机制;
  • 操作者或被操作者的意外行为;
  • 不准确的威胁模型或其他现实原因。

保持客观和专业:在进行审计的时候中,即使某些代码的编写质量可能会让您感到震惊,但也不要使用贬义或嘲讽的语气,而是要坦率而诚实地进行评估。同样,当代码质量高于平均水平时,也不要过分赞美。如果您认为客户提出了不合理的请求,例如为了避免吓唬用户或投资者而掩饰问题,请礼貌地拒绝。

了解审计目标受众对象:审计需要满足目标受众的需求,因此您需要向不同的受众提供不同的审计文档,例如:

  • 如果只有开发人员会阅读您的什么报告,那么一个非正式的轻量级标记语言文档就足够了,这样可以节省编辑时间。
  • 如果报告需要与投资者、合规审计员或高层管理人员共享,那么您就必须提交一份带有颜色和徽标的精美审计报告,以及一份执行摘要。

因此,你必须事先知道谁将阅读审计报告,特别是这份报告是否会被公布。在这种情况下,你需要格外小心,以避免误解和误导性引用相关内容。此外,您还需要与客户密切合作,确保在生产环境中运行的系统得到修补,以防止发现安全缺陷。

做好自己的功课:你必须了解审计行业的最新动态,比如有哪些最新的参考资料文献和最新的漏洞和攻击策略,这会帮助你节省相当多的时间来维护加密组件中常见问题的清单,以及特定于某些变成语言的常见错误和缺陷清单。此外,你还可以创建自己的审计工具,使审计过程自动化并节省时间,但通常市场上已经有不少这种工具了,因此您可以在开始审计之前先熟悉下相关审计工具。

对于客户

确定审计需求并与审计人员进行沟通:在大多数情况下,第一个请求听起来都像是「我们需要对某某项目进行安全审核」,但最好能从项目角度详细说明这意味着什么,包括:

  • 您是否最担心编码错误?
  • 你是否担心代码和规范之间不匹配?
  • 你是否担心出现设计错误?

你需要让审核人员知道您需要将审核的重点放在哪里,以及您认为最大的风险是什么,然后在威胁模型和运营模型的背景下描述这些问题。

尽可能多地共享信息:不要相信「代码足以说明文档」这种话,尤其是面对复杂的加密协议时。即使您的代码清楚地描述了已完成的工作,也无法准确描述出应采取的安全措施,更不用说对抗模型和目标安全属性了。因此,请确保拥有详细的解释文档(甚至包括非正式的轻量级标记语言文档),并与审核人员共享所有设计文档、相关研究论文、以前的审核报告,以及其他可以节省时间并帮助他们掌握被审核系统的任何内容。当审核的目标是使规范与实现相匹配时,请确保将两者之间的已知差异告知审核人员。

以建设性的方式看待流程:把审计报告看作是对项目的认可的确很「诱人」,倘若你收到的审计报告发现了工作中的大量问题,可能会让你感到不开心。但是,你需要明白一件事:审计不太可能对你的产品无条件认可,因为这可能会引起对审计人员潜在利益冲突的质疑。请记住,审计只是一个时间点审核,审计的目标是发现潜在问题,这样就可以帮助你解决这些问题,并改善审计目标的安全态势。审计的结果应该是帮助你的项目或产品得到改进,审计人员应该以专业和客观的态度与你合作,双方共同实现这个目标。

事先就报告内容达成协议:当您只需要在审计报告中对安全性问题进行非正式描述时,你可能不希望为只需要 3 天时间就能搞定的工作付费,尤其是这项工作可能只是简单(重新)编写规范而已。因此,请在工作说明或启动会议的时候准确反映出对审计报告有何期望,以及哪些事情是你不希望看到的。

不要犹豫,向审核员提出挑战:如果您发现一个只有 500 行代码的项目审计时间需要耗费 5 人 / 周工作量,那真的是太可笑了!所以,请直接告诉审计人员你所发现的问题,或者换一家审计公司。另外,相比于那些在项目开发工作中花费大量时间(比如 6 个月)的开发人员,审计人员对代码库的了解程度肯定有所欠缺,因此你需要确认审计方案和实施措施,并且帮助审计人员充分了解代码库,毕竟如果他们不了解你的代码在做什么,那么也不太可能在其中发现错误。

小心处理超售工作包:一些审计公司可能会推广销售一些「额外工作」,比如:「威胁建模」、「安全强化」、「性能优化」、或其他或多或少相关的子项目之类的东西,这些子项目会增加你的咨询费用。所以,甲乙双方都应该事先清楚地理解审计工作内容和目标,以及审计工作将为客户带来哪些价值。但有时候,审计咨询公司的销售人员可能会推销许多「不实用」的服务,如果甲方经理不熟悉具体情况、或是在没有工程师参与时便草草签约,那么可能会上当受骗,这种情况最终也会伤害甲乙双方。

最好不要直说「你通过了审计」:如果您是在博客或社交媒体平台上进行交流,最好不要说「通过审计」这样的话,加密审计和更一般的代码安全性审计只是针对某些常见漏洞进行评估,而且也会受到审计人员的才智和经验所限制,即使此类审计可以使用检查清单,但最终结果绝不是用「通过或不通过」这种简单判断来决定的。

你不一定需要审计报告:你可以要求、或是仅通过 IRC、Slack、Signal 或其他平台非正式地向你的开发人员索要审计报告调查结果。如果你需要一份包含所有调查结果的综合报告来存档,但不需要一份超级正式和精良的文件(例如,当你不打算与投资者或客户分享审计报告时),那么审计人员就不用在报告准备上花费太多时间,这么做也许能帮你节省几天的咨询费。

来源链接:github.com