FlowiseAI/Flowise · critical · Error
Access to this host is denied by policy.
Error message
Access to this host is denied by policy.
What it means
Thrown by isDeniedIP() when the resolved IP matches a CIDR range in the deny list (e.g. 10.0.0.0/8, 127.0.0.0/8, 169.254.169.254 metadata-service range). This is the SSRF protection layer: it prevents the application from making outbound requests to private, loopback, link-local, or cloud-metadata endpoints. The deny list defaults to RFC1918 ranges plus cloud-metadata IPs.
Source
Thrown at packages/components/src/httpSecurity.ts:85
}
for (const entry of denyList) {
if (entry.includes('/')) {
try {
const [rangeAddr, mask] = ipaddr.parseCIDR(entry)
let parsedRange = rangeAddr
let adjustedMask = mask
// Also normalize deny list entries
if (parsedRange.kind() === 'ipv6' && (parsedRange as ipaddr.IPv6).isIPv4MappedAddress()) {
if (mask < 96) continue // malformed IPv4-mapped CIDR — skip
parsedRange = (parsedRange as ipaddr.IPv6).toIPv4Address()
adjustedMask -= 96
}
if (parsedIp.kind() === parsedRange.kind()) {
if (parsedIp.match(parsedRange, adjustedMask)) {
throw new Error('Access to this host is denied by policy.')
}
}
} catch (error) {
throw new Error(`isDeniedIP: ${error}`)
}
} else {
// Try to parse and normalize the deny list entry for consistent comparison
// This handles non-canonical IPv6 addresses (e.g., FE80::1, 2001:0DB8::1)
if (ipaddr.isValid(entry)) {
let parsedEntry = ipaddr.parse(entry)
// Normalize IPv4-mapped IPv6 entries
if (parsedEntry.kind() === 'ipv6' && (parsedEntry as ipaddr.IPv6).isIPv4MappedAddress()) {
parsedEntry = (parsedEntry as ipaddr.IPv6).toIPv4Address()
}
// Compare normalized forms
if (parsedIp.toString() === parsedEntry.toString()) {View on GitHub (pinned to abe4a8601a)
Solutions
- If the request is legitimate and internal, set HTTP_SECURITY_CHECK=false and use HTTP_DENY_LIST to allow only the specific internal host while keeping other protections.
- Pre-resolve and validate the target host before queueing the request, surfacing a clear user-facing error.
- Ensure the URL the user supplied is validated against an allowlist rather than a denylist for high-risk features.
- Do not disable security globally; scope the relaxation to the specific integration via HTTP_DENY_LIST overrides.
Example fix
// before await secureFetch(userSuppliedUrl) // userSuppliedUrl resolves to 10.0.0.5 // after // allow only a specific internal CIDR while keeping default protections elsewhere process.env.HTTP_SECURITY_CHECK = 'false' process.env.HTTP_DENY_LIST = '169.254.169.254,127.0.0.0/8' // narrow deny list await secureFetch(userSuppliedUrl)
Defensive patterns
Strategy: validation
Validate before calling
// Resolve the target and check against the deny list before the real request
import { checkDenyList } from './httpSecurity'
async function preCheck(url: string) {
try {
await checkDenyList(url)
return { ok: true }
} catch (e) {
return { ok: false, reason: String(e) }
}
}
const status = await preCheck(targetUrl)
if (!status.ok) throw new Error(`Blocked: ${status.reason}`) Try / catch
try {
return await secureFetch(url, init)
} catch (e) {
if (String(e).includes('denied by policy')) {
// do not retry; surface a permission error to the caller
throw new ForbiddenError(`URL not allowed: ${url}`)
}
throw e
} Prevention
- Maintain an allowlist (not just a denylist) for user-supplied URLs in high-risk features.
- Never set HTTP_SECURITY_CHECK=false globally; scope relaxations to specific integrations.
- Log denied-IP events so SSRF attempts are visible.
When it happens
Trigger: The target URL's hostname resolves to an IP within a denied CIDR. Concretely: a request to a URL whose DNS resolves to 10.x.x.x, 127.x.x.x, 169.254.x.x, 172.16-31.x.x, 192.168.x.x, or an IPv6 private/link-local range. The CIDR match at line 84 fires after both the request IP and the CIDR entry are normalized.
Common situations: User-supplied URLs in an AI agent tool that the server then fetches (SSRF attack surface). Internal monitoring that legitimately needs to reach a private host. A public hostname that has an A record pointing at a private IP (DNS rebinding). Cloud functions reaching 169.254.169.254 for instance metadata. Testing against localhost.
Related errors
- DNS resolution failed for ${hostname}
- Failed to post ${url}: ${error}
- Failed to make GET request: ${error instanceof Error ? error
- Failed to make POST request: ${error instanceof Error ? erro
- Failed to make PUT request: ${error instanceof Error ? error
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/b84fc0b779b94a30.
Report an issue: GitHub.