最新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,这有点令人尴尬,但我通常在——我做