我审计了自己的开源库,发现了九个安全漏洞。以下是所有漏洞的详情。

发布日期:2026-04-26 09:20:23   浏览量 :1
发布日期:2026-04-26 09:20:23  
1

2026西湖龙井茶官网DTC发售:茶农直供,政府溯源防伪到农户家 

你好,dev.to 👋

如果你读过我之前关于 layercache文章,你就知道它是一个用于 Node.js 的多层缓存库——在单个 get() 调用背后实现了“内存 → Redis → 磁盘”的层级结构,并具备缓存击穿防护、标签失效、熔断机制以及所有生产环境最终需要的成熟功能。

今天我发布了 v1.3.3 版本,它与之前的所有版本都不同。

没有新功能。没有基准测试数据。没有炫酷的应用程序接口(API)新增内容。

只有我在自己的库中发现的九个错误。我想逐一讲解它们——它们是什么,为什么会出现,以及我是如何修复它们的。

有些错误令人尴尬。但所有错误都是真实存在的。

为什么我进行了全面的安全审计

当你开源开发且人们开始真正使用你的作品时,你对代码的看法会有所不同。我以全新的视角和特定的问题重新审视了内部实现:在真实负载下的生产环境中,可能会出现什么问题?

结果是:很多问题。

以下是我发现的所有问题,大致按严重程度排序。

VULN-1(高):keyEpochs 中的无界内存增长

错误描述CacheStackMaintenance 使用一个名为 keyEpochsMap<string, number> 来跟踪写入失效——每次删除或更新键时,其纪元值都会增加,以便过时的异步写入操作知道跳过该键。这个映射表会无限增长。没有上限,没有清理机制。在一个长期运行且写入大量唯一键的服务中,这会导致缓慢的内存泄漏,且情况会随时间推移越来越严重。

修复方案:添加了 MAX_KEY_EPOCHS = 50_000 以及在每次调用 bumpKeyEpochs() 后的清理步骤。当映射表超过限制时,最旧的 10%(纪元值最低的条目)将被移除。

+ const MAX_KEY_EPOCHS = 50_000

  bumpKeyEpochs(keys: string[]): void {
    for (const key of keys) {
      this.keyEpochs.set(key, this.currentKeyEpoch(key) + 1)
    }
+   this.pruneKeyEpochsIfNeeded()
  }

+ private pruneKeyEpochsIfNeeded(): void {
+   if (this.keyEpochs.size <= MAX_KEY_EPOCHS) return
+   const sorted = [...this.keyEpochs.entries()].sort((a, b) => a[1] - b[1])
+   const toDelete = Math.ceil(sorted.length * 0.1)
+   for (let i = 0; i < toDelete; i++) {
+     this.keyEpochs.delete(sorted[i][0])
+   }
+ }

这个问题令人痛心,因为它正是那种在测试中不可见的错误——你只有在进程运行数天且内存图表开始攀升时才会发现它。

VULN-2(中高):FetchRateLimiter 中的无界队列

错误描述FetchRateLimiter 在达到速率限制时,会将每个桶的获取器请求放入队列。该队列本身没有边界。在单个缓存键上持续高争用的情况下,该队列会无限增长——最终消耗无界内存,并导致背压无限累积。

修复方案:添加了 MAX_QUEUE_PER_BUCKET = 10_000。当某个桶的队列已满时,新请求将完全绕过速率限制器,而不是阻塞(在这种故障模式下,可用性优于严格的限流)。

+ const MAX_QUEUE_PER_BUCKET = 10_000

  return new Promise<T>((resolve, reject)

免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。

关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
支持 反馈 订阅 数据
回到顶部