From 9db55844ef22a48fc074cfd16b512d131be79dc3 Mon Sep 17 00:00:00 2001 From: orbisai0security Date: Tue, 5 May 2026 09:59:56 +0000 Subject: [PATCH] fix: V-003 security vulnerability Automated security fix generated by Orbis Security AI --- tools/installer/modules/registry-client.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/installer/modules/registry-client.js b/tools/installer/modules/registry-client.js index 31a38f8d3..479bbb279 100644 --- a/tools/installer/modules/registry-client.js +++ b/tools/installer/modules/registry-client.js @@ -1,3 +1,4 @@ +const crypto = require('node:crypto'); const https = require('node:https'); const yaml = require('yaml'); @@ -103,21 +104,29 @@ class RegistryClient { * @param {number} [timeout] - Timeout in ms (overrides default) * @returns {Promise} Raw file content */ - async fetchGitHubFile(owner, repo, filePath, ref, timeout) { + async fetchGitHubFile(owner, repo, filePath, ref, timeout, expectedSha256) { const apiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${filePath}?ref=${ref}`; const rawUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${ref}/${filePath}`; + let content; // Try GitHub Contents API first (with raw content accept header) try { - return await this._fetchWithHeaders(apiUrl, { Accept: 'application/vnd.github.raw+json' }, timeout); + content = await this._fetchWithHeaders(apiUrl, { Accept: 'application/vnd.github.raw+json' }, timeout); } catch (apiError) { // API failed — fall back to raw CDN try { - return await this.fetch(rawUrl, timeout); + content = await this.fetch(rawUrl, timeout); } catch (cdnError) { throw new AggregateError([apiError, cdnError], `Both GitHub API and raw CDN failed for ${filePath}`); } } + if (expectedSha256) { + const actual = crypto.createHash('sha256').update(content).digest('hex'); + if (actual !== expectedSha256) { + throw new Error(`Integrity check failed for ${filePath}: expected ${expectedSha256}, got ${actual}`); + } + } + return content; } /**