From 0b3cc1c17543ebb864df0f0d72a8751dfd4756ff Mon Sep 17 00:00:00 2001 From: Reinier Criel Date: Thu, 13 Nov 2025 15:50:14 -0800 Subject: [PATCH] Some more cleanup --- .../src/packagemanager/pip/runPipCommand.js | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/safe-chain/src/packagemanager/pip/runPipCommand.js b/packages/safe-chain/src/packagemanager/pip/runPipCommand.js index 4198686..9d68c81 100644 --- a/packages/safe-chain/src/packagemanager/pip/runPipCommand.js +++ b/packages/safe-chain/src/packagemanager/pip/runPipCommand.js @@ -23,20 +23,8 @@ export async function runPip(command, args) { // validates correctly under both MITM'd and tunneled HTTPS. const combinedCaPath = getCombinedCaBundlePath(); - if (!env.REQUESTS_CA_BUNDLE) { - env.REQUESTS_CA_BUNDLE = combinedCaPath; - } - - // https://pip.pypa.io/en/stable/topics/https-certificates/ explains that the --cert option (which we're providing via both INI and PIP_CERT) - // Testing has shown that REQUESTS_CA_BUNDLE alone is not sufficient; PIP_CERT, SSL_CERT_FILE, or pip config cert is also needed in some cases. - - if (!env.SSL_CERT_FILE) { - env.SSL_CERT_FILE = combinedCaPath; - } - - if (!env.PIP_CERT) { - env.PIP_CERT = combinedCaPath; - } + // https://pip.pypa.io/en/stable/topics/https-certificates/ explains that the --cert option (which we're providing via INI file) + // will tell pip to use the provided CA bundle for HTTPS verification. // Proxy settings: prefer GLOBAL_AGENT_HTTP_PROXY, then HTTPS_PROXY, then HTTP_PROXY const proxy = env.GLOBAL_AGENT_HTTP_PROXY || env.HTTPS_PROXY || env.HTTP_PROXY || ''; @@ -45,7 +33,6 @@ export async function runPip(command, args) { const pipConfigPath = path.join(tmpDir, `safe-chain-pip-${Date.now()}.ini`); if (!env.PIP_CONFIG_FILE) { - // Build pip config INI /** @type {{ global: { cert: string, proxy?: string } }} */ const configObj = { global: { cert: combinedCaPath } }; @@ -55,6 +42,7 @@ export async function runPip(command, args) { const pipConfig = ini.stringify(configObj); await fs.writeFile(pipConfigPath, pipConfig); env.PIP_CONFIG_FILE = pipConfigPath; + } else if (fsSync.existsSync(env.PIP_CONFIG_FILE)) { // Existing pip config file present and exists on disk. // Lets merge in our cert and proxy settings if not already present @@ -72,18 +60,17 @@ export async function runPip(command, args) { // Adding CERT and PROXY // If either is already set, there's no neeed to throw an error // MITM might fail and throw later if the proxy config is invalid - // This ensures that no malware will be installed by safe-chain // Cert if (typeof parsed.global.cert === "undefined") { - ui.writeVerbose("Safe-chain: Adding cert to existing PIP_CONFIG_FILE."); + ui.writeVerbose("Safe-chain: Adding cert to temporary PIP_CONFIG_FILE."); parsed.global.cert = combinedCaPath; } // Proxy if (typeof parsed.global.proxy === "undefined") { if (proxy) { - ui.writeVerbose("Safe-chain: Adding proxy to existing PIP_CONFIG_FILE."); + ui.writeVerbose("Safe-chain: Adding proxy to temporary PIP_CONFIG_FILE."); parsed.global.proxy = proxy; } } @@ -93,6 +80,21 @@ export async function runPip(command, args) { // Save to a new temp file to avoid overwriting user's original config await fs.writeFile(pipConfigPath, updated, "utf-8"); env.PIP_CONFIG_FILE = pipConfigPath; + + } else { + // The user provided PIP_CONFIG_FILE does not exist on disk + // PIP will handle this as an error and inform the user + } + + // REQUESTS_CA_BUNDLE, SSL_CERT_FILE and PIP_CERT as extra safety nets. + if (!env.REQUESTS_CA_BUNDLE) { + env.REQUESTS_CA_BUNDLE = combinedCaPath; + } + if (!env.SSL_CERT_FILE) { + env.SSL_CERT_FILE = combinedCaPath; + } + if (!env.PIP_CERT) { + env.PIP_CERT = combinedCaPath; } const result = await safeSpawn(command, args, {