From a2eef8ee05b8eed4fdd172ba4a27e6155dc85689 Mon Sep 17 00:00:00 2001 From: RissRIce Date: Sun, 9 Aug 2026 17:28:22 -0600 Subject: [PATCH] fix(trust): remove stale system anchors --- lib/trust.ts | 5 ++++- tests/upstream-and-system-trust.test.ts | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/trust.ts b/lib/trust.ts index 0db4885..964f8b0 100644 --- a/lib/trust.ts +++ b/lib/trust.ts @@ -380,7 +380,10 @@ export async function install( /** Remove the root from one store. Absent is success — this has to be re-runnable. */ export async function uninstall(store: Store, env: TrustEnv = defaultEnv()): Promise { const before = await status(store, env); - if (!before.installed) return { store, ok: true, changed: false, detail: "was not present" }; + const hasSystemAnchor = store.kind === "ca-certificates" && env.exists(join(store.path, ANCHOR_FILENAME)); + if (!before.installed && !hasSystemAnchor) { + return { store, ok: true, changed: false, detail: "was not present" }; + } try { if (store.kind === "ca-certificates") { diff --git a/tests/upstream-and-system-trust.test.ts b/tests/upstream-and-system-trust.test.ts index 81bad7f..5997412 100644 --- a/tests/upstream-and-system-trust.test.ts +++ b/tests/upstream-and-system-trust.test.ts @@ -9,6 +9,7 @@ // 2. `moshpit-trust` covered browsers and not the system CA store, so `curl` // still failed on a machine that had been "set up". import assert from "node:assert/strict"; +import { join } from "node:path"; import test from "node:test"; import { createPinClient } from "../lib/pins.ts"; @@ -155,6 +156,26 @@ test("uninstalling removes the anchor and rebuilds, in that order", async () => "an anchor removed without a rebuild leaves the bundle still trusting it"); }); +test("uninstalling removes a stale anchor that never reached the bundle", async () => { + const { env, files, ran } = fakeLinux(); + const anchor = join("/usr/local/share/ca-certificates", ANCHOR_FILENAME); + files.set("/usr/local/share/ca-certificates", ""); + files.set(anchor, PEM); + files.set("/etc/ssl/certs/ca-certificates.crt", "unrelated content"); + + const store = discoverStores(env).find((s) => s.kind === "ca-certificates")!; + assert.equal((await status(store, env)).installed, false, + "precondition: the stale file is not active in the system bundle"); + + const result = await uninstall(store, env); + + assert.equal(result.ok, true, result.detail); + assert.equal(result.changed, true); + assert.equal(files.has(anchor), false, + "uninstall must remove a dormant anchor before a later bundle refresh can activate it"); + assert.ok(ran.includes("update-ca-certificates")); +}); + test("status is honest when the file is present but the bundle is not rebuilt", async () => { const { env, files } = fakeLinux(); files.set("/usr/local/share/ca-certificates", "");