Budibase/budibase · error

Only HTTP(S) URLs are allowed.

Error message

Only HTTP(S) URLs are allowed.

What it means

parseUrl() enforces an SSRF-safe protocol allowlist (ALLOWED_PROTOCOLS = http: and https:). If the parsed URL's protocol is anything else - file:, ftp:, data:, javascript:, etc. - it throws Error('Only HTTP(S) URLs are allowed.'). This prevents exfiltration via local file or non-HTTP schemes from server-side outbound requests.

Source

Thrown at packages/backend-core/src/utils/outboundFetch.ts:25

const MAX_REDIRECTS = 5
const ALLOWED_PROTOCOLS = new Set(["http:", "https:"])
const SENSITIVE_REDIRECT_HEADERS = [
  "authorization",
  "cookie",
  "cookie2",
  "proxy-authorization",
]

function parseUrl(url: string): URL {
  let parsed: URL
  try {
    parsed = new URL(url)
  } catch {
    throw new Error("Invalid URL.")
  }

  if (!ALLOWED_PROTOCOLS.has(parsed.protocol)) {
    throw new Error("Only HTTP(S) URLs are allowed.")
  }

  if (parsed.username || parsed.password) {
    throw new Error("URL must not include credentials.")
  }

  return parsed
}

function isRedirect(status: number): boolean {
  return [301, 302, 303, 307, 308].includes(status)
}

async function resolveSafePinnedIp(url: string): Promise<string> {
  const parsed = parseUrl(url)
  const addresses = await resolveAddress(parsed.hostname)
  if (addresses.length === 0) {
    throw new Error("URL is blocked or could not be resolved safely.")

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Use an http:// or https:// URL (use http only for local development)
  2. If the target only supports ftp/etc., fetch it through a separate tool - this helper is HTTP-only
  3. For "localhost:3000" style input, rewrite to "http://localhost:3000"
  4. Sanitize user input to strip or reject non-HTTP schemes before storing

Example fix

// before
await outboundFetch("ftp://files.example.com/data.csv")
// after
await outboundFetch("https://files.example.com/data.csv")
Defensive patterns

Strategy: validation

Validate before calling

// reject non-HTTP schemes before fetching
function isHttpUrl(u: string): boolean {
  try {
    const proto = new URL(u).protocol
    return proto === "http:" || proto === "https:"
  } catch {
    return false
  }
}
if (!isHttpUrl(url)) throw new Error("Only http(s) URLs supported")

Try / catch

try {
  const res = await outboundFetch(url)
} catch (e: any) {
  if (e?.message === "Only HTTP(S) URLs are allowed.") {
    // reject the input or rewrite to an http(s) equivalent
  } else throw e
}

Prevention

When it happens

Trigger: outboundFetch called with "file:///etc/passwd", "ftp://host/file", "data:text/plain,..." or any custom-scheme URL; also triggered by redirects only in the sense that redirects are re-validated elsewhere.

Common situations: Pasting browser-style URLs like "localhost:3000" (parsed protocol becomes "localhost:"); integrations configured with ftp/webhook schemes; malicious payloads probing for SSRF via file://.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/fa1c403b70ea5cae. Report an issue: GitHub.