OWASP Top 10 2024:供应链与"感觉编程"安全风险
最新OWASP版本重点从过时依赖转向供应链安全,新增内存安全和AI"感觉编程"(vibe coding)的风险意识。
完整中文译文
2025 年版 OWASP Top 10 是面向开发者和 Web 应用安全领域的最新标准安全意识文档,广泛代表了业界对 Web 应用所面临的最关键安全风险的共识。
你可以通过 Tanya 的个人网站和她的新播客 DevSec Station 进一步了解她的工作。你还可以使用她的提示词库,学习如何提示 AI 生成安全的代码。
阅读 Tanya 在我们博客上发表的文章。
恭喜 Populist 徽章得主 Rob Kielty,他凭借对“How can I tell IntelliJ's "Find in Files" to ignore generated files?”这一问题的回答获得了该徽章。
Ryan Donovan:大家好,欢迎收听 Stack Overflow 播客,这里专门探讨与软件和技术有关的一切。我是主持人 Ryan Donovan。今天我们要聊的是 OWASP Top 10——或者也可能是 Top 13。今天的嘉宾是一位老朋友,Tanya Janka。你好。
Tanya Janka:你好,Ryan。非常感谢你再次邀请我。
RD:你来我总是很高兴。上次聊天时,你还在从事安全方面的工作,现在你已经成为 OWASP 团队的一员了。能给我们讲讲这是怎么发生的吗?
TJ:当然可以。我以前运营过一个分会,也负责过一个项目。然后 OWASP 基本上就在问:“接下来你打算为我们做什么?”因为我当然还会继续做点什么。当时有很多不同的项目,我分别和它们开会,讨论应该加入哪一个。然后,不知道你是否认识 Star Brown,她是 OWASP 的项目负责人。她是 OWASP 的工作人员,人非常棒。她说,Top 10 团队有点需要有人把他们拖过终点线。而你是那种能把事情做成的人。你热爱 OWASP,他们也热爱 OWASP,那要不我给你们牵个线?于是我见了 Andrew Vanderstock。他是执行董事,同时也是 Top 10 团队的成员。他说:“Tanya,我们每个人都有四百件事要忙。我们就像一群野猫,需要有人来管一管。你想来赶猫吗?”我说:“AppSec 猫?听起来很棒!”于是我们见了面,开了一次会。基本上就是我做了记录:“这些是你们的行动项,这是我们接下来要做的事。下周见。”到了第二周,Neil 就说:“我们能不能直接告诉你,我们有多喜欢你?为什么你十年前没加入我们?”我说:“我不知道,可能当时在忙别的什么傻项目吧。”我们相处得特别融洽。
RD:所谓的傻项目,比如加拿大选举安全,对吧?
TJ:对,对。就是那种傻项目。比如我现在正在努力推动加拿大首部安全编码法律。
RD:总体而言,我第一次接触 OWASP 时,就觉得它是一项非常了不起的资源,可以用来了解当下最受关注的漏洞,对吧?你们每年都会发布 Top 10。今年有什么不同?Top 10 发生了哪些变化?
TJ:实际上,我们每三年才发布一次 OWASP Top 10,这很让人头疼,因为获取数据实在太难了。先不谈数据,具体发生了什么变化?本质上有两项重大变化。第一,我们终于可以把一些内容移出榜单了,这很好。跨站脚本以前是榜单中的独立条目,此外还有服务端请求伪造、跨站请求伪造等。以前,很多具体类型的漏洞都会作为单独条目出现在榜单上。我们非常成功地宣传了这些问题,业界也作出了响应,因此它们跌出了榜单,这让我特别高兴。
不过,两项真正重大的变化之一,是我们将“使用过时且存在漏洞的组件”扩展成了“整个软件供应链”。你的 IDE、CI、代码仓库,以及你用来维护或创建软件的每一样东西,全都属于供应链的一部分。如果它们遭到攻击,我们就麻烦了,对吧?所以我说:“听着,我知道我们没有足够的数据来完全支持这一点,那就问问社区怎么想吧。”结果所有人一致同意,100% 的人都说:“这必须进入榜单。”于是我们说:“看来我们是对的。”如果成百上千名社区成员都认同,那基本上就不会有问题。
另一个变化是“异常情况处理不当”。我们最初审视这个问题时,用的是“代码质量低下”,但我说:“不行,代码质量低下可以涵盖所有条目,什么都能往里装。”而且坦白讲,代码质量低下的修复方案是什么?“你有没有试过少菜一点?有没有试过别这么差?”这种建议完全没有建设性,也毫无帮助。所以我说:“这是一个不可接受的分类,我们需要进一步拆解。我们真正看到的是什么?”
于是我们得到了两个候选项:一个是“应用缺乏韧性”,也就是你的应用不知道该如何恢复运行或维持运行;另一个是“异常情况处理不当”,意味着你的错误处理存在问题。某件事情发生后,你在响应和处理方面做得很差,并且/或者一开始就没有妥善预防它。结果这两项打成了平手。它们的数字几乎一模一样——我记得好像只差两个之类的,真的非常接近。要知道,我们有数百万条结果。
我说:“听着,如果我们解决了异常情况处理不当的问题,就几乎解决了应用韧性的所有问题。但如果只解决应用韧性,它对异常情况处理不当毫无帮助。而 Top 10 里只允许放十项。我想争取那个能同时解决两个问题的条目。”他们说:“你知道吗?这个答案确实相当合理。”
然后我们开始不停地写。我写过书,以前还是一名词曲作者,我很喜欢写作。所以我承担了大量文字撰写工作;Brian 负责了大量——几乎所有——数据工作;Neil 则负责网站、发布和出版。大家就是像这样分别承担团队中的不同工作,对吧?
RD:对,对。在继续聊那个话题之前,还有很多事情是我想了解的。你提到了获取数据的困难,也提到了你们收集的数据。这些数据具体是什么?你们又是如何收集的?
TJ:这真是有史以来最棒的问题。所有正在收听的人,下次我想要你们的数据。基本上,人们通常愿意和我们分享的是:有很多很棒的精品渗透测试公司,会把经过匿名化处理的报告分享给我们;还有许多提供静态分析或动态分析工具的厂商,也会把它们的数据分享给我们。
我们关注的是 CWE,也就是 Common Weakness Enumeration,它描述的是某种模式。例如,注入就是该体系涵盖的一种模式。我们不会使用 CVE,也就是 Common Vulnerabilities and Exposures,因为 CVE 指的是某款产品中的某个具体漏洞。假设你很不明智地运行着 Windows Server 2018 R2 Service Pack,后面再加上一堆版本信息,而我也运行着完全相同的版本,那我们面临的就是同一个漏洞,对吧?
我们想研究的是模式,因为我们关注的是定制软件,而每一款定制软件都是一片独一无二的美丽雪花。像 Spice Girls 唱的那样,我真正、真正想要的数据,是事后分析报告。因为这样我们就能获得供应链方面的信息,对吧?也就能了解凭感觉编程以及其他各种因素,知道事情究竟是如何发生的。
注入仍然是个问题,而且它依然留在 Top 10 中,因为这个问题仍然糟糕透顶。但那次注入究竟是怎么发生的?代码是软件开发者写的吗?是 AI 助手写的吗?还是从全世界最受我们喜爱的论坛上复制来的?他们是从哪里得到这段代码的?注入问题是不是来自他们安装的第三方依赖?而且那个依赖甚至可能本身就是蓄意恶意的,对吧?那次注入究竟是如何发生的?
因为现在已经没有多少开发者还会写出 SQL 注入漏洞了,几乎所有人都知道不应该那么做。这就是我们实际获得的数据与我们希望获得的数据之间的差距。所以下次发起数据征集时,我准备好好求人了。看看效果如何吧。
因为大部分数据都是 Brian 找来的,而我只带来了大约两百万条记录。我在最后时刻找来了两三家厂商——当然,这是和 Brian 找到的数据量相比。不过,我加入这个项目也确实很晚:我们是在 7 月讨论这件事的,我记得第一次会议是在 9 月,而我们 12 月就发布了。对于一个以三年为迭代周期的项目来说,这个速度相当快。
但你能想象吗?你去找一家从事软件开发的组织,说:“嘿,能把你们所有安全事件的事后分析报告都给我们吗?”他们会说:“不,你们不能。”
RD:当然。我知道,对于某些数据泄露事件,公司必须进行披露,而且很多人本来也会发布事后分析报告。这些报告有帮助吗?因为我记得第一次查看 OWASP 时,它列出了一长串 CVE,我当时就觉得:“哇,这真够全面的。”
TJ:既是,也不是。上周我在丹佛参加了一个叫 Snowfrog 的会议,并做了这场演讲。讲到一半时,我说,好吧,这是一个 AppSec 会议,所以几乎所有人都从事应用安全工作。我问:“在座有谁遇到过软件安全事件?”大概三分之一的人举了手。然后我说:“好吧,那么剩下那些已经遇到安全事件、却还不知道的人,我们来聊聊这个问题。”因为只要你的软件放在互联网上,我可以向你保证,你就在遭受攻击。很多人甚至完全不知道该关注什么,也根本没有意识到攻击正在发生。所以,我现在不仅要求你能够发现安全事件,还要求你有能力响应,并且确实有时间和精力进行事后复盘、为我写出报告,再以匿名版本分享出来。比如,我会帮助别人处理他们的——因为我也做咨询,诸如此类的,对吧?我会和他们的 AppSec 项目团队合作,然后说:“我们来统计一下你们经历过的安全事件吧。”但他们大多数人根本没有这样的数据。他们不知道自己遇到过多少起安全事件,其中多大比例与 AppSec 有关,造成了多少损失,花费了多少工时,也不知道目前面临的情况是什么,以及为什么值得在安全项目上投入。大多数人只是在疲于救火。
RD:主动预防式的安全工作似乎仍然有点遥远,不是吗?
TJ:因为 Ryan,我关心的并不是某个愚蠢的扫描器发现了什么。我关心的是什么真正攻了进来,也就是什么更频繁地遭到攻击,以及这些攻击中哪些手段真正奏效。遗憾的是,我们并没有真正获得多少这方面的数据。比如,当我们查看 Verizon 的数据泄露报告,或者 CrowdStrike 的年度数据泄露报告时,还有其他几家公司也会发布一些报告,也要感谢 Mandiant。有很多公司正在这个领域开展非常出色的工作。但有时候,即便只是他们报告这些事件的方式,也和我脑海中的理解不一样。比如,过去两三年里,他们经常会说:“哦,发生了这起大规模供应链攻击。”但在我看来,我会说:“他们攻陷了一名软件开发者。他们攻陷了一个人。”随后,这件事又撬开了供应链中的多个环节。那并不是针对供应链的攻击,而是针对一个人的攻击——一个权限极高、能力极强的人。所以,我也不知道。
RD:我的意思是,我和安全从业者聊过,安全系统中最薄弱的环节似乎确实是人,对吧?攻击人也是成本最低的手段。
TJ:但我们没有保护他们。Ryan,我们没有保护软件开发者。几乎每次我去一家公司做培训,都会问:“有多少人以前接受过任何形式的安全编码培训?”没有人举手。每次都是这样,除非我之前已经去过,现在是再次回来。然后我们还会问:“为什么会发生这种情况?”我会说:“你们觉得是为什么?”我们面对着这么巨大的攻击面,却还在装作:“啦啦啦,它根本不存在。”
RD:对,对。那么我想聊聊供应链攻击。我觉得现在这个概念涵盖了很多东西。以前可能只是“更新你的软件”,但现在每个人都有如此多的依赖,还有那么多来自 NPM 的文件。情况到底有多糟糕?
TJ:以前的答案是开启自动更新。现在的答案是,请不要开启自动更新。
RD:我知道还有其他人在做类似的事情,比如 Dino 有一个 JSR,我记得它似乎提供了某种验证机制。还有其他类似的选项,能够提供良好的安全性和控制措施吗?这里所谓的良好控制措施又是什么?
TJ:有一些像 .NET 这样的选择,背后有一家大型公司支持,拥有安全项目,并且正在努力把事情做好,对吧?然后,对于 NPM 和其他组织,我们依赖的是志愿者。这些志愿者做了大量工作。他们非常努力,也非常尽职。我并不是在贬低他们的工作。但整个系统的设置方式,并没有让他们具备成功的条件。这样说有道理吗?据我所知,他们没有一支全职负责、专门受雇来完成这项工作的安全团队。如果事实并非如此,我很乐意接受纠正。
那么,最佳实践是什么?理想情况下……每次开始处理一份代码时,我都希望你在开发环境中尽可能多地更新依赖,但只更新到发布已满七天或更久的版本。为什么?因为如果某个东西是被人故意植入恶意内容的,我们通常会在最初七天内发现它,随后它就会从其所在的平台中被移除。所以,如果你能设置为只采用发布七天或更久的版本,那会很好。然后,我希望你运行所有测试,确保你对它完全满意,并且它包含你需要的一切,接着把版本固定下来,对吧?如果可以使用锁文件,并把锁文件提交到代码仓库,那也非常好。随后,在沿着发布链逐步向上推进时,始终使用这个固定版本,避免它意外地被换成其他令人措手不及的东西。因为我们这些安全从业者不喜欢意外。我们反对惊喜派对。
然后,理想情况下,你还应该运行一种叫作软件成分分析的工具,并让它启用可达性分析。所谓可达性,首先,这类工具会告诉你有 20 个依赖。哈哈哈,仿佛依赖数量真的会这么少一样。而这些依赖还有自己的依赖,那些依赖又有朋友、室友,以及其他朋友。
RD:然后他们每个人再联系两个人。
TJ:对,没错。接着,它会告诉你这些依赖中哪些存在漏洞。不过,关键在于这个漏洞实际上是否能通过你的代码路径触达。也就是说,你调用它的方式是否会沿着调用链一路深入,最终抵达依赖中存在问题的那部分代码。对于这些可达的漏洞,我肯定会立刻修复,对吧?不要发布明知存在严重问题的代码。这才是理想做法。
还有一种较新的公司类型,而且这样的公司有很多。我不太想点名,因为我不想推广任何特定公司,但它们基本上提供的是依赖健康度分析。比如,它们会告诉你:“是的,这个依赖两周前刚刚更新,但它只有一名维护者,而且那个人住在朝鲜。你对这个依赖感觉如何?”对吧?然后你可能会想:“也许我应该换一个依赖。”又或者,我们还没有在某个依赖中发现任何漏洞,但它已经四年没有更新,而且也没有维护者。那么,我认为这个依赖看起来同样不太健康。
这是一类新工具,我们还没有为它创造出什么神奇的缩写名称。所以,如果你要搜索,可以直接搜“依赖健康度”。我的意思是,如果我们能够偶尔运行这两类工具中的任意一种,查看一下结果,看看自己对所选依赖的感觉如何,那会很有帮助。而且,如果这些供应商发现某个依赖已经变成恶意软件,也会通知我们,比如 polyfill 事件。这样的案例实在太多了,对吧?它原本是一个合法依赖,后来就不是了。
RD:是的,因为——也许是 XZ 那次事件,只有一名维护者,他精疲力竭,最后基本上把项目交给了一个恶意行为者。
TJ:那个恶意行为者在项目里做了两年志愿工作,以此建立信任。然后维护者说:“嘿,我可以退出了吗?”这在志愿工作中很正常。我记得自己以前运营过一家非营利组织,后来退出了董事会。而就在我退出董事会的那一刻,整个组织基本上崩溃了。他们之间发生了一些奇怪的争执,大家都在说:“我想当领导,我想当领导。”结果组织大概一个月内就垮了。在我运营它多年之后发生这种事,你可以想象,这相当令人失望。
所以,当你把某件事情的控制权交给一名志愿者时,对方已经为你做了多年志愿工作,你认为他非常出色,也觉得自己了解他,结果他接手之后做出了那种事,你会想:“哇,原来你一直都在等待这一刻。哇。”作为一个亲身经历过类似事情的人,我会惊叹于其中需要多大的耐心。虽然我的经历不是发生在代码项目中,但本质上仍然类似,对吧?你会看到某种巨大的转变。
所以,我觉得你根本不知道该如何提前发现。因为我也维护过开源项目,有人过来做志愿贡献,然后他们确实非常出色。通常我发现,要么他们很棒,要么他们出现后帮你修复一两个 bug,接着就消失了。因此,我们通常可以预期的情况是:要么他们来了以后表现出色,要么他们出现一阵子,然后因为忙于其他事情而消失。一般来说,最糟糕的情况也不过是:“哦,他修复了五个 bug,然后我已经六个月没见到他了。”
RD:你知道,我见过一些公司专注于供应链安全,会接管被放弃的开源项目以确保它们的安全。从.NET的例子来看,解决这个安全问题的一个办法似乎是让利益相关方有所投入,对吧?
TJ:是的。坦率地说,我们作为一个行业,正在用爱好者的工作构建生产产品,有时这些产品关系到人们的生命。然后当代码达不到专业水准时,我们就感到沮丧。Log4J事件发生时,人们对那些维护者——我想有三个——进行了疯狂的批评。我想说的是,那些哥们有自己的生活要过。他们有孩子。他们可能有一个伴侣说,"嘿,我三天没见到你了。你在干什么?"这是他们的爱好。然后人们对他们进行了猛烈的批评。我想说的是,不,不,不,不,不。他们没有因此获得报酬。而且,你自愿对他们的代码进行过安全审查吗?没有。你给过他们的项目捐款,好让他们能做渗透测试吗?没有。
TJ:说到代码的安全审查,最近Anthropic的Mythos发布了,它到处发现了疯狂的bug,包括在OpenBSD中发现的一个30年的bug。
TJ:还有OpenSSL。
RD:真的吗?又一个。
TJ:我想他们在OpenSSL中发现了七个Heartbleed级别的漏洞。
RD:这说明了什么,关于这些每个人都依赖的项目的安全水平?
TJ:所以我教授安全编码,我们一起审查代码,大多数代码都很糟糕。它能做这个功能,但从安全角度来看,这不是我们被教授的方式。我在90年代上的大学。我在2000年毕业,他们教我,Ryan,我应该把代码中的所有秘密保存下来。不仅要保存生产密钥,还要保存每一层的密钥。开发环境和QA环境,这样我们就能破坏系统的每一层,这样我们就不会丢失它。那是最佳实践。那就是我被教授的。所以大多数人从未接受过培训。即使他们刚从大学毕业,也没有安全编码培训。然后他们在做这个工作,特别是在自由项目上。没有安全团队,对吧?人们会问,为什么安全专家不自愿来帮忙?我的回答是,因为有太多的付费工作要做。我们字面上永远做不完。我永远不会有休息的时间。当我从开发转向软件安全时,我从每天完成所有工作、收件箱几乎为零,变成了无论我多晚离开办公室。我永远完不成仅仅今天的工作,永远。我实际上在处理安全事件时在办公室过了好几个晚上。在企业中,你永远,永远做不完这些工作。我怎么有时间去保护一堆开源项目的安全?我没有这个时间。而且为什么我要这样做,当我可以为一家公司获得一大笔报酬来做这个时,对吧?为什么我要这样做?我喜欢钱。我知道这似乎不像是这样,因为我做了很多免费工作,因为我一直在做社区工作之类的。我知道似乎我可能讨厌钱,但我实际上有点喜欢它。
RD:好吧,是的,是的。我是说,不足以让你只做这个,你知道。
TJ:只做付费工作。
RD:只为了钱做。Mythos的声明似乎在另一方面说,好吧,所有代码都是垃圾,但也许所有黑客也都是垃圾吧?像这些bug已经存在多年了。是的,我是说,或者也许人们一直在入侵但没有被抓住。
TJ:所以一个问题是Mythos以不同的方式观察,因为它不是人类。它不像人类那样观察。它从不同的角度来看,对吧?所以有这个因素。就像我的威胁模型与你的威胁模型不同一样。比如有人在半夜敲你的门,你会想,这个混蛋把我吵醒了,而我则想,哦天哪,我要被杀害了,对吧?我们有不同的威胁模型。但我也认为我们只是还没有时间检查每一件事。所以黑客。他们为什么要看OpenBSD?他们这样做的目的是什么?有人付钱让他们进行彻底的代码审查吗?因为就像我在加拿大选举委员会时,我们支付了某人来进行代码审查,我们修复了一切。然后我们支付了某人来进行渗透测试,我们修复了一切。然后我们支付了另一个人来进行代码审查。那家伙发现了很多东西。然后我们支付了另一次渗透测试,我们修复了那个人发现的每一件事。然后选举日实际上超级无聊,这很棒。什么都没发生,我们没有上新闻,太棒了。我觉得可能还有bug在某个地方,因为我们只有四个意见。你明白吗?还有很多意见我们可以听到。而且,FreeBSD有一个全职安全团队吗?安全团队还做什么其他事情?所以我觉得……有一个叫Katie Paxton Fear的女士,我多年前在我的播客上采访过她,然后现在我们是朋友,她完全忍受我。她做API渗透测试。那是她的专长。她说在她测试过的所有API中。她遇到过访问控制被破坏、授权问题。在她的整个职业生涯中100%。无论如何,她从未没有发现它。她很聪明,但像……她是世界上最好的吗?谁知道呢,对吧?但她每次都会发现它。所以我们做得不够好。我对我们能做什么有很多想法。我认为我们需要找到一个新的方式来做这个。也许安全控制不应该由每个团队重新编写,对吧?我们购买身份产品。为什么我们没有授权产品?为什么我们没有输入验证产品?为什么我们没有错误处理产品,这样我们实际上能知道安全事件正在发生?
RD:我认为有访问控制和身份验证产品,但我认为对于一个团队来说,编写自己的OAuth实现是很容易的。
TJ:对他们来说写一个很容易。但我不知道他们是否很容易完美地写一个。
RD:当然不。但你刚刚实现了它。为什么你要为此付费呢?
TJ:然后在这之上,我们有人正在使用AI来帮助他们。Ryan,这有点令人尴尬,但我通常在——我做