ToolJet/ToolJet · critical · QueryError

URL scheme blocked

Error message

URL scheme blocked

What it means

SSRF guard that rejects URLs whose scheme is in config.blockedSchemes. Typical blocked schemes are file://, gopher://, ftp://, dict:// — protocols that can be abused to read local files or hit arbitrary TCP ports. The check uses isSchemeBlocked against the configured list and only runs when blockedSchemes is non-empty.

Source

Thrown at marketplace/plugins/common/lib/ssrf-protection.ts:535

        'URL contains private IP address in credentials section which could be used for SSRF',
        { hostname, credentials: potentialIP }
      );
    }
  }

  // 1. Static hostname blocklist — defense-in-depth before any DNS resolution
  if (isBlockedHostname(hostname)) {
    throw new QueryError(
      'Hostname blocked',
      'This hostname is not allowed for security reasons',
      { hostname }
    );
  }

  // 2. Check for blocked schemes
  if (config.blockedSchemes && config.blockedSchemes.length > 0) {
    if (isSchemeBlocked(scheme, config.blockedSchemes)) {
      throw new QueryError(
        'URL scheme blocked',
        `The URL scheme '${scheme}' is not allowed. Blocked schemes: ${config.blockedSchemes.join(', ')}`,
        { scheme, blockedSchemes: config.blockedSchemes }
      );
    }
  }

  // 3. Check if hostname is a private IP address.
  // On self-hosted (allowPrivateNetworks=true) only block dangerous ranges
  // (metadata endpoints, loopback) — RFC1918 is allowed for internal services.
  const ipCheckFn = config.allowPrivateNetworks ? isDangerousPrivateIP : isPrivateIP;
  if (ipCheckFn(hostname)) {
    throw new QueryError(
      'Private IP address blocked',
      'Direct access to private IP addresses is not allowed for security reasons',
      { hostname }
    );
  }

View on GitHub (pinned to 20602a8e10)

Solutions

  1. Use http:// or https:// for the request instead of file/gopher/ftp.
  2. If a non-http scheme is genuinely required on a self-hosted instance, review and adjust blockedSchemes in the SSRF config after a security review.
  3. Sanitize template variables that could inject a scheme prefix.
  4. Log these attempts — they are frequently reconnaissance.

Example fix

// before — 'file:///etc/passwd'
// after  — fetch the resource over HTTPS from a proper endpoint: 'https://config-store.example.com/passwd'
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_SCHEMES = new Set(['http:','https:']);
function isSafeScheme(url: string): boolean { try { return ALLOWED_SCHEMES.has(new URL(url).protocol); } catch { return false; } }

Try / catch

try { await validateUrlForSSRF(urlString); }
catch (e) {
  if (e instanceof QueryError && e.message === 'URL scheme blocked') { /* require http/https */ }
  throw e;
}

Prevention

When it happens

Trigger: A URL with a non-http(s) scheme that appears in blockedSchemes: file:///etc/passwd, gopher://internal:6379/_FLUSHALL, ftp://, dict://. Also fires if a template variable prefix produces an unexpected scheme.

Common situations: An end-user (or attacker) supplies file:// to read server files; a misconfigured template concatenates a scheme; a legacy integration that legitimately used ftp and is now blocked by the SSRF policy.

Related errors


AI-assisted analysis of ToolJet/ToolJet@20602a8e10 (2026-08-13). Data as JSON: /api/errors/5e73c06b6f518828. Report an issue: GitHub.