Have I Been Pwned 2.0 正式上线:全新数据泄露查询平台的技术升级与功能解析

Troy Hunt宣布Have I Been Pwned 2.0正式发布,详细介绍了网站的技术重构、新功能如专用仪表板、域名搜索优化、API文档改进,以及使用.NET 9.0、Azure服务和Cloudflare的技术架构升级。

Have I Been Pwned 2.0 正式上线!

2025年5月20日

经过漫长的努力和马拉松式的开发,全新的Have I Been Pwned(HIBP)网站终于正式上线!去年二月,我首次向公共代码库提交了重新品牌化服务的代码,并于今年三月进行了软启动。在此期间,我们完全重建了网站,改变了几乎所有网页的功能,添加了大量新功能,甚至今天还推出了一个商品商店😎。让我带您了解一些亮点,系好安全带!

搜索功能

HIBP的标志性功能是首页上的大搜索框,现在它更好了——它有彩花!不过,不是所有人都能看到,只有大约一半的用户会看到庆祝响应。这种故意欢快的响应是有原因的:随着Charlotte和我与全球众多用户交流,一个主题反复出现:HIBP有点 playful。它不是一个充满连帽衫、锁图标和恐吓“暗网”的可怕地方。相反,我们旨在更易于大众接受,提供事实性、可操作的信息,没有夸张。彩花枪(是的,有好几个,而且是动画的)让气氛轻松一些。另一种情况是您会看到红色响应:

我们曾短暂考虑过在这个页面上采用更轻松的处理方式,但 somehow 一点悲伤的长号似乎不太合适,所以我们选择了更含蓄的响应。但现在,它在一个时间线上,您可以按时间倒序滚动查看,每个泄露事件都总结了发生了什么。如果您想要更多信息,我们有一个全新的页面,我稍后会谈到。

首先,一个小变化:我们从网站上移除了用户名和电话号码搜索支持。用户名搜索是在2014年Snapchat事件中引入的,电话号码搜索是在2021年Facebook事件中引入的。仅此而已。这是我们唯一一次加载这些类型的数据,有几个很好的理由。首先,与电子邮件地址相比,它们很难从泄露中解析出来,我们只是使用正则表达式提取电子邮件地址(我们已经开源了相关代码)。用户名是一个字符串。电话号码,嗯,这取决于情况。它们不仅仅是数字,因为如果您正确国际化它们(就像Facebook事件中那样),它们前面还有一个加号,但格式经常五花八门。而且我们无法发送通知,因为没有人“拥有”一个用户名,而发送短信到电话号码比发送电子邮件昂贵得多。此外,除了这两个事件外,HIBP中的其他所有事件都有电子邮件地址,所以如果我们问“我被泄露了吗?”,我们总是可以回答这个问题,而无需加载这两个难以解析的字段,这些字段在大多数泄露中通常不存在。当旧网站提供在搜索框中接受它们时,它造成了混乱和支持 overhead:“为什么我的号码不在[某个]泄露中?!”这就是为什么它从网站上消失了,但我们在API中保留了支持,以确保不破坏任何东西…只是不要期望在那里看到更多数据。

泄露页面

我们创建这个新页面的原因有很多,尤其是首页的搜索结果变得太 busy,我们想把细节放在其他地方。所以,现在我们为每个泄露事件都有一个专用页面,例如:

这主要是我们已经有的信息(尽管以更用户友好的方式显示),但新页面的独特之处在于提供了更 targeted 的建议,关于泄露后该做什么:

我最近写了关于这个部分,以及我们计划如何识别其他合作伙伴,能够为发现自己处于泄露中的人提供适当的服务。例如,身份保护提供商对许多数据泄露非常有意义。

现在我们已经上线,我们还将努力充实这个页面,添加更多泄露和用户特定数据。例如,如果服务支持2FA,那么我们会特别指出,而不是依赖上面的通用建议。密码钥匙也是如此,我们会添加一个部分。最近在英国与NCSC的讨论是关于添加本地化数据泄露指导,例如,向英国用户显示NCSC徽标和链接到他们的资源(该资源推荐检查HIBP🙂)。

我相信我们还可以做更多,所以如果您有任何好主意,请在下面给我留言。

仪表板

现在,我们将所有这些不同的地方统一到一个中央仪表板:

从左边的导航栏一眼看去,您可以看到很多熟悉的功能,这些功能几乎不言自明。这些结合了大众相关的功能和更面向业务的功能。它们现在都在一个“登录”后面,该登录在显示前验证对电子邮件地址的访问权限。将来,我们还会添加密码钥匙支持,以避免需要先发送电子邮件。

仪表板方法不仅仅是把现有功能移动到一个旗帜下;它还将为我们提供一个平台,在未来构建需要先进行电子邮件地址验证的新功能。例如,我们经常被要求提供让人们能够订阅他们家庭电子邮件地址的通知,但让通知发送到不同的地址。我们中的许多人为他人提供技术支持,这将是一个真正有用的功能,有意义地放在您已经验证了电子邮件地址的地方。所以,请期待这个功能, among many others。

域名搜索功能

这个功能花费的时间比大多数其他功能 combined 还要多。我们在这里尝试了很多,从一个更简洁的已验证域名列表开始:

搜索结果现在提供了更简洁的摘要,并添加了按电子邮件地址和热门请求的新功能过滤——仅最新泄露(它在下拉菜单中):

所有这些搜索现在只从API返回JSON,整个仪表板充当单页应用,所以一切都非常快速。上面的过滤是纯客户端针对域名搜索的完整JSON进行的,我们测试了这种方法, domains 有超过25万个被泄露的电子邮件地址,仍然可行(尽管可以说,您真的希望通过API获取该数据,而不是在浏览器窗口中滚动查看)。

域名所有权验证也完全重写,有一个更简洁、更简单的界面:

我们还有工作要做,使非电子邮件验证方法更 smooth,但以前也是如此,所以至少我们没有退步。那很快就会发生, promise!

API

首先:API本身没有变化。这个更新不会破坏任何东西!

在UX重建GitHub仓库上有一个关于API文档正确方法的讨论。普遍共识是OpenAPI,我们开始使用Scalar走这条路。事实上,您甚至可以看到Stefan在这里做的工作:haveibeenpwned.com/scalar:

它非常酷,尤其是它以各种不同语言记录样本的方式,甚至有一个测试运行器,这实际上是浏览器中的Postman。很酷,但我们就是没时间完成它。因此,我们暂时保留了旧文档,只是进行了样式化,使其看起来像网站的其余部分(我认为仍然很 slick),但我们确实打算在不再承受如此大发布压力时,转向Scalar实现。

商品商店

您知道还有什么很棒吗?商品!不,严肃地说,多年来我们收到了很多对HIBP品牌商品的请求,现在,我们来了:

我们现在实际上有一个真实的商品商店在merch.haveibeenpwned.com!考虑到我们必须做多少机械工作来使所有新东西工作,这可能是我们时间的最糟糕使用,但这是Charlotte的一个 passion project,所以是的,现在您实际上可以购买HIBP商品。一切都是通过Teespring完成的(我在哪里听过这个名字?!),那里列出的所有东西都是成本价——我们绝对不赚钱,这只是一个为社区的有趣倡议🙂

我们也尝试了他们的贴纸选项,但它们远远不及我们在Sticker Mule上的小单件商店已有的东西,所以目前,那仍然是笔记本电脑装饰的首选。或者只是去抓取开源 artwork,从您喜欢的任何地方打印您自己的。

技术细节

我们仍然在Microsoft Azure上运行原始服务,使用App Service for the website、“serverless” Functions for most APIs(那里仍然有一些异步的,作为基于浏览器功能的一部分被调用)、SQL Azure “Hyperscale”和存储账户功能,如队列、blob和表。几乎所有的编码都是C# with .NET 9.0 and ASP.NET MVC on .NET Core for the web app。Cloudflare仍然扮演着重要角色,有很多代码在workers中,数据在R2存储中,以及所有他们的好东西围绕WAF和缓存。我们现在也 exclusively 使用他们的Turnstile服务进行反自动化,并完全抛弃了Google的reCAPTCHA—— big yay!

前端现在是最新一代的Bootstrap,我们使用SASS for all our CSS and TypeScript for all our JavaScript。我们在冰岛的(另一位)人Ingiber刚刚在界面上做了一项绝对出色的工作,大大超出了我们所有的期望。我们现在拥有的远远超出了我们开始这个过程时的预期,很大一部分是Ingiber的能力,能够把一个简单的要求变成一件美丽的事物😍我很高兴Charlotte、Stefan和我上个月在雷克雅未克与他共度时光,分享了一些啤酒。

我们还对网站性能进行了一些可衡量的改进。例如,我在取下旧网站之前运行了一个Pingdom网站速度测试:

然后在新网站上运行它:

所以我们削减了28%的页面大小和31%的请求。加载时间大致相同(而且变化很大),但对右边列中的所有值有 solid measures 是一个非常令人满意的结果。还要考虑任何Web开发人员多年来会看到的关于网页变得多大的评论,而11年后我们在这里削减了 solid double-digit percentages!

最后,任何可能被 remotely 解释为跟踪或广告膨胀的东西都不在那里,因为我们 simply don’t do any of that🙂事实上,我们唯一真正的流量统计数据是基于Cloudflare在流量流过他们的边缘节点时看到的情况。而那个1Password产品放置,一如既往,只是文本和图像。我们甚至不跟踪出站点击,那是他们的事,如果他们想在登陆页面上捕获它。这实际上使与想要产品放置的身份盗窃公司的讨论更加困难,因为他们习惯于获得侵入性跟踪产生的数字,但我们不会以其他方式做。

AI

我想在这里快速提一下这个,因为AI似乎要么 constantly overblown,要么 denigrated。要么它将解决世界的问题,要么它只是产生“slop”。我特别在这次重建中广泛使用了Chat GPT,尤其是在时间紧张、大脑炸裂的最后几天。以下是一些它产生重大影响的例子:

我使用Bootstrap图标从这里:https://icons.getbootstrap.com/

什么是一个好图标来说明一个标题叫“Index”?

这是在最后关头,当我们意识到我们没有时间正确实施Scalar时,我需要快速迁移所有现有的API文档到新模板。那个页面上有超过2,000个图标,这种方法意味着每次找到正确的图标大约需要30秒。

我们在旧网站上删除了一些页面,但在推出之前,我想确切知道那里有什么:

为我写一个PowerShell脚本来爬取haveibeenpwned.com并写出它找到的每个唯一URL

然后:

现在写一个脚本来获取它找到的所有路径,并查看它们是否存在于stage.haveibeenpwned.com上

它也找到了好东西,比如我忘记迁移的security.txt文件。它还找到了从未存在的东西,所以这是通常的“信任,但验证”情况。

还有无数的小事情,每次我需要从一些CSS建议到配置Cloudflare规则到.NET Core web app中的 idiosyncrasies,正确答案都在几秒钟内。我会说它90%的时间是正确的, too,如果您现在在软件开发工作中没有 aggressively 使用AI(而且我相信还有更好的方式),我 pretty confident 地说“您做错了”。

旅程到这里

很难解释投入了多少,这远远超出了今天您在网站上看到的内容。似乎是小事,比如对使用条款和隐私政策的 minor revisions,这需要许多小时的时间和数千美元与律师(只是对我们如何处理数据的 minor updates 以及新服务如窃取者日志的反映)。我们在周日凌晨我的时间推出了新网站,几乎一切顺利:

一两个小故障,我们已经修复并快速推送,仅此而已。我实际上等到现在,上线两天后,才发布这篇文章,以便我们能够先 iron out 尽可能多的东西。自那时以来,我们已经推送了十几个新版本,只是为了快速迭代和精炼。TBH,这有点 intense,并且是一个 enormously time-consuming 的努力,主导了我们的焦点,尤其是在发布前的最后几周。只是为了 drive that point home,我 literally 在周一早上 first thing 收到了一个健康警报:

没有什么比经验数据更能说明问题!那个最后周末我们上线时特别 brutal;我不认为几十年来我为软件发布投入了那么多高强度时间。

Have I Been Pwned 现在是我四分之一人生的 passion。我在2013年建造的东西从未 intended 带我这么远或持续这么久,如果我诚实的话,我有点 shocked。我觉得我们通过这个新网站和新品牌建造的东西已经将这个 little pet project 提升到了一个严肃的服务,具有新的专业水平。但我希望在阅读本文时,您看到它保持了服务一直伟大的 everything,我很高兴今天仍然在这里写关于它的第205篇博客文章。感谢阅读,现在去享受新网站吧😊

编辑(最初发布几小时后):让我扩展一下Cloudflare的Turnstile,因为它会解释一些人看到的一些 idiosyncrasies:

这是一种反自动化方法,不涉及将流量交给Google(像reCAPTCHA那样),并且可以完全 invisibly 实施。它有更侵入性的实现,但我们在这里尝试 seamless。它涉及一些Cloudflare脚本在浏览器中运行并提供挑战,然后与HTTP请求一起提交并在服务器端验证。自2023年以来,我们以某种形式在HIBP上拥有它,它可以很棒…直到它不是。如果挑战失败,接下来会发生什么?这取决于。

在我们真的需要阻止机器人的表单上(例如,任何发送电子邮件的),失败的Turnstile挑战最初只是显示一个红色错误。现在它说:

我们的反自动化过程认为您是一个机器人,您显然不是!尝试表现得像一个人,再次点击按钮,如果它仍然行为不当,给页面一个重新加载。

我们经常发现第二次点击或页面重新加载解决了问题,所以 hopefully 这 sends people in the right direction。如果没有,我们将需要查看更 in-your-face 的Turnstile实现,显示一个您需要交互的小部件。要自己尝试并查看它 action,试试仪表板登录页面。

Turnstile heavily 特色的另一个地方是在网站根目录的主搜索页面。我们不希望那个API被机器人击中,所以那里是 must have。在这里,像在新网站的其他页面上一样,我们异步发布到API端点,并随请求发送挑战令牌。然而,我们在首页上做不同的是,如果挑战失败并在发布到HIBP端点时返回HTTP 401(您还会看到响应体“Invalid Turnstile token”),我们 meant to be falling back to a full page post。当我们首次推出新网站时,这没有发生。但现在它发生了🙂

当完整页面回发发生时,Cloudflare将呈现一个托管挑战。这更具侵入性,但也更可靠,然后将 serve 与您无论如何都会看到的相同结果,尽管通过完整页面加载。我们在深度链接的账户页面上实施相同的托管挑战逻辑,您可以在这里看到:https://haveibeenpwned.com/account/test@example.com

根据Cloudflare统计数据,大约82%的所有我们发出的挑战成功解决:

在18%没有解决的中,许多将是由于Turnstile阻止的机器人 doing exactly what it’s meant to do。很可能是个位数百分比的请求是真实人类被 impeded,我们需要寻找方法降低那个数字,但至少 fallback positions 现在改进了。如果您遇到问题,给网站一个好的刷新,看看您的情况,并在下面留下您的反馈。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计