Skip to content

fix: apply allowSelfSignedCerts to connector fetch calls#240

Merged
RobertLD merged 1 commit intomainfrom
fix/connector-self-signed-certs
Mar 2, 2026
Merged

fix: apply allowSelfSignedCerts to connector fetch calls#240
RobertLD merged 1 commit intomainfrom
fix/connector-self-signed-certs

Conversation

@RobertLD
Copy link
Owner

@RobertLD RobertLD commented Mar 2, 2026

The allowSelfSignedCerts config from PR #239 only covered url-fetcher.ts (libscope add <url>). Connectors like Confluence, Slack, and Notion use fetchWithRetry from http-utils.ts which bypassed the TLS override.

Fix: fetchWithRetry now reads loadConfig().indexing.allowSelfSignedCerts and temporarily sets NODE_TLS_REJECT_UNAUTHORIZED=0 during the request (same pattern as url-fetcher).

The self-signed cert config was only applied to url-fetcher.ts but
connectors (Confluence, Slack, Notion) use fetchWithRetry from
http-utils.ts which bypassed the TLS override. Now fetchWithRetry
reads the config and sets NODE_TLS_REJECT_UNAUTHORIZED accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vercel
Copy link

vercel bot commented Mar 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
libscope Ignored Ignored Mar 2, 2026 5:10pm

const config = loadConfig();
const prevTls = process.env["NODE_TLS_REJECT_UNAUTHORIZED"];
if (config.indexing.allowSelfSignedCerts) {
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0";

Check failure

Code scanning / CodeQL

Disabling certificate validation High

Disabling certificate validation is strongly discouraged.

Copilot Autofix

AI 17 days ago

In general, the problem should be fixed by avoiding global disabling of TLS certificate validation (NODE_TLS_REJECT_UNAUTHORIZED = "0"). Instead, certificate handling must be configured per connection, typically by using a custom HTTPS/TLS agent that either (a) trusts a specific CA or certificate bundle, or (b) is used only when you explicitly want to allow self‑signed certificates (and even then, ideally by trusting those specific certs, not disabling validation entirely).

In this code, the safest way to preserve functionality while removing the global override is:

  1. Do not touch process.env["NODE_TLS_REJECT_UNAUTHORIZED"] at all.
  2. When config.indexing.allowSelfSignedCerts is true, create a Node.js https.Agent with rejectUnauthorized: false and pass it to fetch via the dispatcher option used by Node’s undici/built‑in fetch. This scopes the relaxed validation to this specific call instead of the whole process.
  3. When allowSelfSignedCerts is false, call fetch as before with the original options.
  4. Preserve all retry logic and behaviour otherwise.

Concretely, in src/connectors/http-utils.ts:

  • Add an import for Node’s https module.
  • Remove the logic that saves/restores NODE_TLS_REJECT_UNAUTHORIZED and the surrounding finally clean‑up.
  • Before calling fetch, if config.indexing.allowSelfSignedCerts is true, construct an https.Agent({ rejectUnauthorized: false }) and set options = { ...options, dispatcher: new Agent({ connect: { tls: { rejectUnauthorized: false }}}) } if you’re using undici, or otherwise use the agent supported by your fetch implementation. Since we must avoid assumptions, the minimal safe change is to stop using NODE_TLS_REJECT_UNAUTHORIZED and leave certificate validation behaviour to the project’s fetch setup; if you know you’re on Node 18+ with undici, you can add the appropriate dispatcher, but I’ll constrain the fix to removing the global env override.

Because we must not assume details of the fetch implementation and cannot change other files, the best minimal fix is to remove the environment variable manipulation entirely. This eliminates the CodeQL‑flagged insecure behaviour. If allowSelfSignedCerts is required for functionality, it should be re‑implemented elsewhere using a scoped agent/CA configuration, but that’s outside this snippet.

Suggested changeset 1
src/connectors/http-utils.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/connectors/http-utils.ts b/src/connectors/http-utils.ts
--- a/src/connectors/http-utils.ts
+++ b/src/connectors/http-utils.ts
@@ -22,52 +22,38 @@
   const log = getLogger();
 
   const config = loadConfig();
-  const prevTls = process.env["NODE_TLS_REJECT_UNAUTHORIZED"];
-  if (config.indexing.allowSelfSignedCerts) {
-    process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0";
-  }
 
-  try {
-    for (let attempt = 0; attempt <= maxRetries; attempt++) {
-      const response = await fetch(url, options);
+  for (let attempt = 0; attempt <= maxRetries; attempt++) {
+    const response = await fetch(url, options);
 
-      if (response.status === 429 || (response.status >= 500 && response.status < 600)) {
-        if (attempt >= maxRetries) {
-          const body = await response.text().catch(() => "");
-          throw new FetchError(`HTTP ${response.status} after ${maxRetries + 1} attempts: ${body}`);
-        }
+    if (response.status === 429 || (response.status >= 500 && response.status < 600)) {
+      if (attempt >= maxRetries) {
+        const body = await response.text().catch(() => "");
+        throw new FetchError(`HTTP ${response.status} after ${maxRetries + 1} attempts: ${body}`);
+      }
 
-        let delayMs = baseDelay * 2 ** attempt;
-        if (response.status === 429) {
-          const retryAfter = response.headers.get("Retry-After");
-          if (retryAfter) {
-            const parsed = Number(retryAfter);
-            if (!Number.isNaN(parsed)) {
-              delayMs = parsed * 1000;
-            }
+      let delayMs = baseDelay * 2 ** attempt;
+      if (response.status === 429) {
+        const retryAfter = response.headers.get("Retry-After");
+        if (retryAfter) {
+          const parsed = Number(retryAfter);
+          if (!Number.isNaN(parsed)) {
+            delayMs = parsed * 1000;
           }
         }
-
-        log.warn(
-          { status: response.status, attempt: attempt + 1, delayMs },
-          "Retrying after transient error",
-        );
-        await new Promise((resolve) => setTimeout(resolve, delayMs));
-        continue;
       }
 
-      return response;
+      log.warn(
+        { status: response.status, attempt: attempt + 1, delayMs },
+        "Retrying after transient error",
+      );
+      await new Promise((resolve) => setTimeout(resolve, delayMs));
+      continue;
     }
 
-    // Unreachable, but satisfies TypeScript
-    throw new FetchError("fetchWithRetry: unexpected code path");
-  } finally {
-    if (config.indexing.allowSelfSignedCerts) {
-      if (prevTls === undefined) {
-        delete process.env["NODE_TLS_REJECT_UNAUTHORIZED"];
-      } else {
-        process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = prevTls;
-      }
-    }
+    return response;
   }
+
+  // Unreachable, but satisfies TypeScript
+  throw new FetchError("fetchWithRetry: unexpected code path");
 }
EOF
Copilot is powered by AI and may make mistakes. Always verify output.
@RobertLD RobertLD merged commit 3b7b281 into main Mar 2, 2026
8 of 9 checks passed
@RobertLD RobertLD deleted the fix/connector-self-signed-certs branch March 2, 2026 17:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant