Repository navigation
computerd: Build the binary on Node 22.23.4 - #269
Conversation
Eight eMudhra intermediate CAs were issued with keys anyone can recover from the certificates. They chain to emSign ECC Root CA - G3 and, through Sectigo cross-signs, to AAA Certificate Services. Node 22.22.3, which the computerd binary was built on, still ships emSign ECC Root CA - G3 in its bundled root store, and the binary verifies TLS against that store. A client in computerd would therefore accept a certificate forged with one of the compromised keys. Node 22.23.4 drops both roots and rejects the intermediates. Pin the binary build and the next-image workflow to it. build-bin now runs the target Node binary before injecting the SEA blob and fails when its bundled store still contains either root, so a later pin to an unpatched release cannot reintroduce them silently. The check runs only for the target matching the build host; the other target shares the same Node version.
馃 Changeset detectedLatest commit: 99dbaf3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
build-bin checked a target's bundled root store by running its Node binary, so it could only check the target matching the build host. On Linux the macOS binary shipped unchecked, and on macOS the Linux one did. Node compiles its root store into the executable as PEM text, so read the store from the file instead. Every target is now checked on any build host. Finding fewer than 100 certificates also fails the build, so a change in how Node embeds the store cannot pass as a clean store.
| const text = (await readFile(nodeBinary)).toString("latin1"); | ||
| const blocks = text.match(EMBEDDED_PEM_PATTERN) ?? []; | ||
| const subjects = []; | ||
| for (const pem of blocks) { | ||
| try { | ||
| subjects.push(new X509Certificate(pem).subject.split("\n")); |
There was a problem hiding this comment.
馃煛 Cross-target root checks lack tests
The new checkRootStore extraction has no tests for either target or for rejecting distrusted roots. This violates the repository's requirement to test new behavior.
Learn more
The build validates bundled certificates for Linux and macOS by reading each target's executable. Its new extraction and parsing branch is not exercised by any test. A passing build today does not protect this safeguard against a later regression. COLLABORATORS.md requires tests for new behavior.
Example: A fixture with 116 valid certificates plus CN=AAA Certificate Services must make checkRootStore reject the build; a fixture with fewer than 100 certificates must also fail. Neither case currently has a regression test.
Recommended fix: Extract checkRootStore into a testable module and add fixtures or generated test binaries covering clean stores, both prohibited subjects, malformed PEM blocks, and a store below minimumBundledRoots. Verify that buildTarget invokes it for both targets.
Was this helpful? React with 馃憤 or 馃憥 to provide feedback.
Eight eMudhra intermediate CAs were issued with keys anyone can recover from the certificates. They chain to emSign ECC Root CA - G3 and, through Sectigo cross-signs, to AAA Certificate Services. Node 22.22.3, which the computerd binary was built on, still ships emSign ECC Root CA - G3 in its bundled root store, and the binary verifies TLS against that store. A client in computerd would therefore accept a certificate forged with one of the compromised keys.
Node 22.23.4 drops both roots and rejects the intermediates. Pin the binary build and the next-image workflow to it.
build-bin now runs the target Node binary before injecting the SEA blob and fails when its bundled store still contains either root, so a later pin to an unpatched release cannot reintroduce them silently. The check runs only for the target matching the build host; the other target shares the same Node version.