From 035780be4ab902912718e7d79bde9f7d8d6ebd5c Mon Sep 17 00:00:00 2001 From: anupamme Date: Wed, 16 Sep 2026 13:46:18 +0000 Subject: [PATCH] harden: the api in Api.js The Api --- src/Api.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Api.js b/src/Api.js index 32aabd8d..f82b4766 100644 --- a/src/Api.js +++ b/src/Api.js @@ -41,6 +41,20 @@ const fetchWithRetry = async (url, options, retries = 0) => { } } +const isDisallowedExternalUrl = (url) => { + try { + const { protocol, hostname } = new URL(url) + + if (!/^https?:$/.test(protocol)) { + return true + } + + return /^(?:localhost|0\.|10\.|127\.|169\.254\.|172\.(?:1[6-9]|2\d|3[01])\.|192\.168\.|\[?::1\]?|\[?fd[0-9a-f]{2}:)/i.test(hostname) + } catch { + return true + } +} + class Api { static _sendVerbatim = async (path, verb, optionsRaw) => { const { getAgentForUrl, ...options } = optionsRaw || {} @@ -52,6 +66,10 @@ class Api { throw new errors.ConfigurationError('Base URL has not been set - use Files.setBaseUrl() to set it') } + if (isExternal && isDisallowedExternalUrl(path)) { + throw new errors.ConfigurationError('Refusing to send request to a disallowed URL') + } + const url = isExternal ? path : `${baseUrl}${Files.getEndpointPrefix()}${path}`