Merge pull request #338 from AikidoSec/cleanup-cert-bundle

Cleanup generated cert bundles
This commit is contained in:
bitterpanda 2026-03-19 18:38:18 +01:00 committed by GitHub
commit a7a94d9211
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 5 deletions

View file

@ -8,6 +8,9 @@ import { X509Certificate } from "node:crypto";
import { getCaCertPath } from "./certUtils.js";
import { ui } from "../environment/userInteraction.js";
/** @type {string | null} */
let bundlePath = null;
/**
* Check if a PEM string contains only parsable cert blocks.
* @param {string} pem - PEM-encoded certificate string
@ -54,6 +57,11 @@ function isParsable(pem) {
* @returns {string} Path to the combined CA bundle PEM file
*/
export function getCombinedCaBundlePath() {
if (bundlePath)
{
return bundlePath;
}
const parts = [];
// 1) Safe Chain CA (for MITM'd registries)
@ -99,9 +107,23 @@ export function getCombinedCaBundlePath() {
}
const combined = parts.filter(Boolean).join("\n");
const target = path.join(os.tmpdir(), `safe-chain-ca-bundle-${Date.now()}.pem`);
fs.writeFileSync(target, combined, { encoding: "utf8" });
return target;
bundlePath = path.join(os.tmpdir(), `safe-chain-ca-bundle-${Date.now()}.pem`);
fs.writeFileSync(bundlePath, combined, { encoding: "utf8" });
return bundlePath;
}
/**
* Remove the generated CA bundle file from disk.
*/
export function cleanupCertBundle() {
if (bundlePath) {
try {
fs.unlinkSync(bundlePath);
} catch (err) {
ui.writeVerbose(`Failed to cleanup the create bundle at ${bundlePath}`, err)
}
bundlePath = null;
}
}
/**

View file

@ -2,7 +2,7 @@ import * as http from "http";
import { tunnelRequest } from "./tunnelRequestHandler.js";
import { mitmConnect } from "./mitmRequestHandler.js";
import { handleHttpProxyRequest } from "./plainHttpProxy.js";
import { getCombinedCaBundlePath } from "./certBundle.js";
import { getCombinedCaBundlePath, cleanupCertBundle } from "./certBundle.js";
import { ui } from "../environment/userInteraction.js";
import chalk from "chalk";
import { createInterceptorForUrl } from "./interceptors/createInterceptorForEcoSystem.js";
@ -115,12 +115,16 @@ function stopServer(server) {
return new Promise((resolve) => {
try {
server.close(() => {
cleanupCertBundle();
resolve();
});
} catch {
resolve();
}
setTimeout(() => resolve(), SERVER_STOP_TIMEOUT_MS);
setTimeout(() => {
cleanupCertBundle();
resolve();
}, SERVER_STOP_TIMEOUT_MS);
});
}