Fix SSRF (Server Side Request Forgery) in AdonisJS
SSRF in AdonisJS occurs when the backend blindly trusts user-supplied URLs to fetch external resources, potentially exposing internal services (Redis, DBs) or Cloud Metadata (169.254.169.254). As a researcher, I see this most often in image uploaders or URL previewers. If you're not validating the protocol, resolving the IP, and checking it against a blacklist, your server is an open proxy for the attacker's recon.
The Vulnerable Pattern
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' import axios from 'axios'export default class ProxyController { public async fetch({ request, response }: HttpContextContract) { const { url } = request.all()
// CRITICAL VULNERABILITY: Direct sink for user input. // Attacker can pass 'http://localhost:6379' or 'http://169.254.169.254/latest/meta-data/' const res = await axios.get(url) return response.send(res.data)
} }
The Secure Implementation
To mitigate SSRF, we implement a multi-layered defense-in-depth approach. First, we enforce a protocol whitelist (HTTP/HTTPS) to prevent URI schemes like file:// or gopher://. Second, we manually resolve the hostname to an IP address before the request is made. This allows us to use the 'private-ip' library to check if the destination is a local or internal resource (e.g., 127.0.0.1, 10.0.0.0/8). Finally, we disable redirects (maxRedirects: 0) to prevent 'Time-of-Check to Time-of-Use' (TOCTOU) bypasses where a safe URL redirects to a malicious internal one after our initial validation.
import { parse } from 'url' import { lookup } from 'dns/promises' import axios from 'axios' import isIpPrivate from 'private-ip'export default class SafeFetcher { public static async get(targetUrl: string) { const parsed = parse(targetUrl)
// 1. Protocol Whitelisting if (!['http:', 'https:'].includes(parsed.protocol!)) { throw new Error('Forbidden Protocol') } // 2. Resolve DNS to prevent DNS Rebinding and check IP const { address } = await lookup(parsed.hostname!) // 3. Block Private/Internal IP Ranges (RFC 1918) if (isIpPrivate(address)) { throw new Error('Access Denied: Internal Network Target') } // 4. Use the resolved IP or strictly validated URL with no redirects return axios.get(targetUrl, { timeout: 3000, maxRedirects: 0, validateStatus: (status) => status === 200 })
} }
Protect your AdonisJS API
Don't rely on manual checks. GuardAPI's Gemini 3 Pro engine detects SSRF (Server Side Request Forgery) and logic flaws in seconds.
Run Automated AuditVerified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.