加密领域的安全岗位需要稳定而缜密的工作。评估一个复杂协议的安全性是一个真正具有挑战性的任务,而威胁建模是一种结构化的方法,可以在早期发现薄弱环节,从而及时修复。这个过程并不复杂,它依赖工程师和业务人员对风险与优先事项的理解,进而制定一条清晰的路径来打造更强健的产品。在OPLabs,我们有一支庞
加密领域的安全岗位需要稳定而缜密的工作。评估一个复杂协议的安全性是一个真正具有挑战性的任务,而威胁建模是一种结构化的方法,可以在早期发现薄弱环节,从而及时修复。这个过程并不复杂,它依赖工程师和业务人员对风险与优先事项的理解,进而制定一条清晰的路径来打造更强健的产品。
在 OP Labs,我们有一支庞大的安全团队。即使拥有丰富的专业知识,我们也不总能凭直觉判断安全工作的重点应该放在哪儿。威胁建模指引着我们前进,并为我们的版本发布提供信心。
在这篇文章中,我会介绍我们如何进行威胁建模,让你也能有信心确保自己正在修补正确的安全漏洞。
这个过程易于掌握、富有启发性,尤其适合喜欢学习新方法、提升安全技能的你。让我们开始吧。
为了弄清楚威胁建模在整体安全策略中的位置,我们先介绍一个基础的安全模型。
当我们开发某个功能时,会逐步叠加多个安全防护层。最基本的就是单元测试的全面覆盖。在做单元测试时,人们常常倾向于只测试“快乐路径”——也就是各参与方都按照预期行为操作的情况。这是测试代码应有行为的方式,我们认为它很重要。
但当你追求测试的“全面覆盖”时,也意味着你在验证这个功能不会做它不应该做的事。你需要检查:当某个参与方行为异常时,系统是否能产生一个受控、可预期的结果。
测试过程中,你常常会意识到,参与者可能会做一些意料之外的操作,而你需要将这种操作的损害范围限制在他们自己、其他用户,或者你的功能本身。
这种对“异常行为”的控制,是应用安全的关键。我们几乎不可能预见所有可能出错的情境,但只要我们能减少意外情况的空间,整体风险就会大大降低。
在单元测试之外,我们还会不断叠加更多安全手段,比如模糊测试(fuzzing)、符号执行、形式化验证、安全审计、漏洞赏金等等——这些都是为了发现功能可能出现意外结果的新路径。
但问题来了:你该使用哪些安全措施?你做得够多了吗?你覆盖了对的组件吗?你是否需要定制安全方案?
答案就是:威胁建模(Threat Modelling)。这正是我们确认是否在对的地方部署了足够安全手段,从而获得发布信心的方法。
威胁建模的最佳起点,是思考最糟糕的情况会是什么。这个清单常常无时无刻不萦绕在从事加密安全工作的人的脑海中。
我在 Yield Protocol 工作时,我们最担心的是用户资产被盗;但我们也会担心在资产转移过程中被我们不小心“丢”进某个无法找回的地方,以及其他一些令人头疼的情况。
如今在 OP Labs,我们最先关注的是桥接资产的安全性,其次是链长时间停滞的问题,然后是一些较轻的问题。
一旦你把所有负面结果列出来,就可以轻松根据严重性从高到低排序。之后你就可以从最严重的后果开始做威胁建模,因为它们最可能需要你立刻采取缓解措施。
让我们从零开始构建一个威胁模型。先做一个简单的,再做一个稍复杂的。威胁模型可以有很多构建方式,但我们在 OP Labs 使用的是一个非常简单的流程:构建树状结构。
树的根节点表示你想要避免的结果。比如桥接资金被盗,或链停滞至用户注意到的程度。从每个根节点出发,我们列出可能导致该结果的所有事件。这些通常是系统内的组件失败,但也可以是任何外部条件。比如,在一个简单的链上开放式交易所的例子中,我们要避免的结果是交易池资产被盗。我们将每个交易池的代码任意分成两个组件:一个是支付函数,另一个是转账函数,因为我们认为这两个组件任一出错,都可能导致资产被盗。
这个划分方式是任意的,但它足够有效。只要每个叶子节点之间没有重叠,将复杂系统划分为更简单组件的任何方式都能帮助你找出风险所在。你可以咨询构建该功能的工程师,他们通常能很好地按组件划分系统。当然你也可以加入一些遗漏组件,比如“底层区块链软件出现 bug 会怎样”。你觉得相关就写进去,后面你会搞清楚它是否重要。
接下来,我们来看一个更复杂的例子:一个链上代币化金库,使用外部预言机计算资产价值。我们决定深入查看这个组件。
这个模型比上一个复杂,但构建方式一样,都是从上至下,直到我们认为已经深入到足够具体的组件为止。有时候,为了某个高层组件失败,会需要两个子组件同时失败才能触发。这种情况很常见,尤其是某些安全措施已经在位的情况下。你也可以反过来建树,从叶子往上。即选一个组件,假设它出错了,然后思考它如何引发更高层组件故障,最终被用户察觉。这就是一个完整的“从组件到后果”的路径。如果某处存在捕捉该路径的安全机制,也要把它加为一个节点,并假设它也失败了。
无论你是自上而下,还是自下而上构建树,最终你都会有若干棵树。每棵树代表一个你想避免的结果,树中包含导致该结果的所有组件层级。
有时候,同一组件/子树会出现在多个树中,因为它可能通向多个不良后果。这种情况下,我们优先处理最严重的结果。
在 OP Labs,我们将每个事件的可能性划分为四个等级:
为某个后果赋予精确概率很难,但我们通常更容易对某个小组件的逻辑理解程度做出判断。系统中每个部分的专家,通常能给出相当合理的判断,只要我们让他们明白“只需要大致靠谱”就行。
然后我们把各节点的概率往上传递。默认的逻辑是:
比如说,在一棵树中,某个二级节点是紫色,但它与一个黄色节点通过 AND 连接,所以合并后是黄色;但如果另一个子树是红色,则红色的概率会主导根节点。最终结果是这个根节点的风险至少是红色(即一年内很可能发生)。
现在我们已经了解了各个组件故障如何导致不良后果,可以着手缓解这些风险。
以我们的例子来说,假设我们能接受在第一年内金库不被盗,因为我们预计在那之前就会有长期解决方案。那么,我们的目标就是降低所有红色或紫色叶子的风险。比如我们有两个目标节点,一个是红色,一个是紫色。我们向开发者寻求建议,他们建议:给红色节点加上校验和(checksum),给紫色节点做形式化验证。
不过,由于紫色节点与一个黄色节点是 AND 的关系,所以我们其实不需要给紫色节点做形式化验证。只要我们实现校验和,整体风险已经被控制在目标水平。这是最终调整后的树:
这个过程可以对每个后果重复执行,直到你制定出一个完整的缓解措施工作计划,把风险控制在可接受范围内。
在 OP Labs,我们已经为多个版本采用过这个威胁建模系统的不同变体。每次建模后,我们都能识别出风险不可接受的组件,并针对这些组件设计缓解方案。
我们目前正在将此方法应用于 Interop 版本,这可能是我们迄今为止最复杂的一次发布。威胁建模让我们能够挖掘各位工程师在各自组件中的专业知识,深入了解系统每个部分的风险,并规划出一条通往安全发布的路径。
我们识别出许多需要避免的不同后果,这些后果所对应的威胁树总计超过 100 个节点。为了降低这些后果发生的概率,我们正在实施数十项安全缓解措施。
通过本文所描述的流程,你也能提升对系统安全性的信心,确保你在正确的地方做正确的事情,为安全软件发布保驾护航。这对我们所有人都有好处。
在 OP Labs,我们正在招聘愿意在前沿技术与安全领域深耕的人才。如果你想和世界级的团队一起打造世界级的项目,欢迎联系我!
Join us
微信公众号: Optimism 中文
Twitter: https://x.com/Optimismzh
Telegram:https://t.me/optimism_cn
Medium: https://medium.com/@optimismcn
微信群:公众号后台回复 【加群】
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!