fix(desktop): exclude expired Windows trust roots with real-certificate coverage (#107014)

* fix(desktop): filter expired Windows CAs and deduplicate trust roots

* test(desktop): verify CA expiry and deduplication with real certificates

* test(desktop): cover Linux alongside macOS CA no-op policy

Co-authored-by: Gabriel Stoltemberg <215755014+Stoltemberg@users.noreply.github.com>

* chore: map CA trust contributors for release attribution

* style(desktop): match CA filtering to lint rules

---------

Co-authored-by: wliu-dev <249166551+wliu-dev@users.noreply.github.com>
Co-authored-by: Gabriel Stoltemberg <215755014+Stoltemberg@users.noreply.github.com>
This commit is contained in:
Austin Pickett
2026-09-09 21:34:06 -04:00
committed by GitHub
parent 09183ae7bb
commit b8d09d785d
5 changed files with 96 additions and 5 deletions
@@ -0,0 +1,37 @@
// Synthetic self-signed CAs; no private keys are retained. Tests freeze time
// between the expired root's 2025 expiry and the other roots' 2035 expiry.
export const bundledRoot = `-----BEGIN CERTIFICATE-----
MIIBWDCB/6ADAgECAhRU6TyqBZA4z6kjw80UZ4JJcTGTezAKBggqhkjOPQQDAjAi
MSAwHgYDVQQDDBdIZXJtZXMgdGVzdCBidW5kbGVkUm9vdDAeFw0yMDAxMDEwMDAw
MDBaFw0zNTAxMDEwMDAwMDBaMCIxIDAeBgNVBAMMF0hlcm1lcyB0ZXN0IGJ1bmRs
ZWRSb290MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzYsepxCA6/L5jOtyaK7c
tonILmwaEH7S3SaXZkCPMPPn7ciN08fFIQvEK2xmexibsIW/07/y+EQsCsytdXD7
TqMTMBEwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiAoOvvNIWtl
56kb5jeS67rndvpGdvRVfA8hu/d7qPUXHgIhAOVWB0FmymX7/ptbzS9os2DB7S8M
bsTP81ca6H4QAVMO
-----END CERTIFICATE-----
`
export const privateRoot = `-----BEGIN CERTIFICATE-----
MIIBWDCB/6ADAgECAhQpNQF0JRsR2+tIXdZrGV71uQLqnjAKBggqhkjOPQQDAjAi
MSAwHgYDVQQDDBdIZXJtZXMgdGVzdCBwcml2YXRlUm9vdDAeFw0yMDAxMDEwMDAw
MDBaFw0zNTAxMDEwMDAwMDBaMCIxIDAeBgNVBAMMF0hlcm1lcyB0ZXN0IHByaXZh
dGVSb290MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbWaJLnFzm5gFQFK4u1Sg
+ZSXFpfKOuKVLiLU9K2xfg9glPZQY+25Eh+7eMkeOWbOOgXbQE9gmQ2Lsjs+G57C
fqMTMBEwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiAuMyPaHvKJ
BTNIxn3kTlG/7rQ8iSBJ/iTYSxC/7sLzcwIhAJZno/XUb+l9XQfNgADj7jHRorx7
Hfp7kgJ01+X1LAKU
-----END CERTIFICATE-----
`
export const expiredRoot = `-----BEGIN CERTIFICATE-----
MIIBWDCB/6ADAgECAhQpDur4nw/PAq6RuWUbTzDvuICiojAKBggqhkjOPQQDAjAi
MSAwHgYDVQQDDBdIZXJtZXMgdGVzdCBleHBpcmVkUm9vdDAeFw0yMDAxMDEwMDAw
MDBaFw0yNTAxMDEwMDAwMDBaMCIxIDAeBgNVBAMMF0hlcm1lcyB0ZXN0IGV4cGly
ZWRSb290MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEe+50enZvxfDciM9yMPBo
BHYtfdV4eSv017W1GgC3OyDQpypA7Usio1jSy6VXGSGTKpKVPTeMhTPtQLSpbf2z
eKMTMBEwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiAduJa3QWjS
+lF7cmuGdgUezYQLEIUqAPsPhJxgzGNmiwIhAKIyQ1uxv4Mzl0Mou7AiUGpqy8Xr
CKxqXEB0ODeqpB0N
-----END CERTIFICATE-----
`
@@ -1,9 +1,36 @@
import assert from 'node:assert/strict'
import { X509Certificate } from 'node:crypto'
import { test } from 'vitest'
import { afterEach, test, vi } from 'vitest'
import { bundledRoot, expiredRoot, privateRoot } from './fixtures/windows-system-ca'
import { installWindowsSystemCaTrust, type NodeTlsCaApi } from './windows-system-ca'
afterEach(() => vi.restoreAllMocks())
test('excludes expired roots and deduplicates real certificates with defaults first', () => {
vi.spyOn(Date, 'now').mockReturnValue(new Date('2026-01-01T00:00:00Z').getTime())
const tlsApi = fakeTlsApi(
[expiredRoot, bundledRoot, bundledRoot, 'unparseable-default'],
[expiredRoot, bundledRoot.replaceAll('\n', '\r\n'), privateRoot, privateRoot, 'unparseable-system']
)
const result = installWindowsSystemCaTrust(tlsApi, 'win32')
assert.deepEqual(tlsApi.installed, [[bundledRoot, 'unparseable-default', privateRoot, 'unparseable-system']])
assert.deepEqual(result, { applied: true, systemCertificateCount: 2, totalCertificateCount: 4 })
})
test('excludes a root at its exact expiry while retaining valid defaults', () => {
vi.spyOn(Date, 'now').mockReturnValue(new X509Certificate(expiredRoot).validToDate.getTime())
const tlsApi = fakeTlsApi([bundledRoot], [expiredRoot])
const result = installWindowsSystemCaTrust(tlsApi, 'win32')
assert.deepEqual(tlsApi.installed, [[bundledRoot]])
assert.deepEqual(result, { applied: true, systemCertificateCount: 0, totalCertificateCount: 1 })
})
function fakeTlsApi(
defaults: string[] = ['bundled-ca', 'extra-ca'],
system: string[] = ['windows-root-ca']
@@ -34,7 +61,7 @@ test('installs Windows system CAs without dropping existing defaults', () => {
})
})
test('does not inspect or replace CAs outside Windows', () => {
test.each(['darwin', 'linux'] as const)('does not inspect or replace CAs on %s', platform => {
let reads = 0
const tlsApi: NodeTlsCaApi = {
@@ -48,7 +75,7 @@ test('does not inspect or replace CAs outside Windows', () => {
}
}
const result = installWindowsSystemCaTrust(tlsApi, 'darwin')
const result = installWindowsSystemCaTrust(tlsApi, platform)
assert.equal(reads, 0)
assert.deepEqual(result, {
+27 -2
View File
@@ -1,3 +1,5 @@
import { X509Certificate } from 'node:crypto'
interface NodeTlsCaApi {
getCACertificates(type?: 'default' | 'system'): string[]
setDefaultCACertificates(certificates: string[]): void
@@ -31,12 +33,35 @@ function installWindowsSystemCaTrust(tlsApi: NodeTlsCaApi, platform = process.pl
}
}
const certificates = [...defaultCertificates, ...systemCertificates]
// Prefer existing defaults. Expired Windows roots can divert OpenSSL onto
// an expired chain even when a valid bundled trust path exists.
const seen = new Set<string>()
const now = Date.now()
const keepCertificate = (pem: string): boolean => {
try {
const certificate = new X509Certificate(pem)
if (certificate.validToDate.getTime() <= now || seen.has(certificate.fingerprint256)) {
return false
}
seen.add(certificate.fingerprint256)
} catch {
// Leave PEM acceptability to Node if its X.509 parser cannot inspect it.
}
return true
}
const filteredDefaults = defaultCertificates.filter(keepCertificate)
const filteredSystem = systemCertificates.filter(keepCertificate)
const certificates = [...filteredDefaults, ...filteredSystem]
tlsApi.setDefaultCACertificates(certificates)
return {
applied: true,
systemCertificateCount: systemCertificates.length,
systemCertificateCount: filteredSystem.length,
totalCertificateCount: certificates.length
}
} catch (error) {
@@ -0,0 +1 @@
Stoltemberg
@@ -0,0 +1 @@
wliu-dev