GuardAPI Logo
GuardAPI
GuardAPI Logo GuardAPI

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 Audit

Verified 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.