Ssrf in Adonisjs with Jwt Tokens
Ssrf in Adonisjs with Jwt Tokens — how this specific combination creates or exposes the vulnerability
Server-Side Request Forgery (SSRF) in AdonisJS when JWT tokens are involved is a compound risk that arises from two factors: the framework’s flexible HTTP client usage and the way applications handle or propagate identity tokens. SSRF occurs when an attacker can coerce the server into making arbitrary outbound HTTP requests to internal or external endpoints. In AdonisJS, this commonly surfaces through routes or controllers that fetch resources from user-supplied URLs, often to integrate with third-party services or to validate remote data.
When JWT tokens are used for authentication, developers sometimes embed or forward these tokens in outbound requests without strict validation. For example, an endpoint might accept a URL from a client, add an Authorization header containing a JWT extracted from the incoming request, and then call the provided URL. An attacker can supply an internal address such as http://169.254.169.254/latest/meta-data/iam/security-credentials/ (AWS instance metadata) and have the server relay the JWT in the request, potentially exposing credentials or sensitive metadata to a remote attacker if the JWT is also accepted by the target service.
Moreover, SSRF in AdonisJS with JWT tokens can be exacerbated by overly permissive URL resolution, lack of hostname allowlisting, and insufficient network segmentation. If the application resolves short-lived JWTs and uses them to call other internal microservices, an SSRF not only exposes the application but may also facilitate lateral movement. The framework’s reliance on community HTTP libraries means that without explicit safeguards, developers might inadvertently permit redirects to internal IPs or misuse of service tokens.
In a black-box scan by middleBrick, such patterns are detected as high-severity SSRF risks, especially when combined with JWT-forwarding behavior. The scanner does not rely on internal architecture but highlights the presence of unvalidated URL inputs and token propagation that can be abused under SSRF conditions.
Jwt Tokens-Specific Remediation in Adonisjs — concrete code fixes
Remediation centers on strict input validation, removing unnecessary token propagation, and applying the principle of least privilege for outbound calls. Below are concrete, syntactically correct examples for AdonisJS that mitigate SSRF when working with JWT tokens.
1. Validate and restrict target URLs
Never forward user-supplied URLs directly. Use a hostname allowlist and reject private IP ranges. The example below uses Node’s built-in url module and a small utility to block internal destinations.
import { URL } from 'url'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
const allowedHosts = ['api.github.com', 'api.example.com']
function isPrivateIp(host: string): boolean {
// simplified check for demo; consider using a robust library in production
const ipRegex = /^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.)/)
return ipRegex.test(host)
}
export default class ResourcesController {
public async fetchExternal({ request, response }: HttpContextContract) {
const targetUrl = request.input('url')
try {
const parsed = new URL(targetUrl)
if (!allowedHosts.includes(parsed.hostname) || isPrivateIp(parsed.hostname)) {
return response.badRequest({ error: 'Invalid or disallowed target URL' })
}
// safe to proceed
} catch {
return response.badRequest({ error: 'Malformed URL' })
}
// continue with request
}
}
2. Avoid forwarding JWTs to user-provided endpoints
Do not automatically copy the incoming Authorization header to outbound requests. Instead, use service-specific credentials stored securely (e.g., environment variables or a secrets manager) and scope them to the minimal required permissions.
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { createClient } from 'urllib'
export default class DataController {
public async proxyData({ request, response }: HttpContextContract) {
const targetUrl = request.input('url')
// Validate targetUrl as shown above before proceeding
const client = createClient({
followRedirects: false,
})
// Use a service-specific API key, not the caller's JWT
const serviceApiKey = process.env.SERVICE_API_KEY
const { data, res } = await client.request(targetUrl, {
headers: {
Authorization: `Bearer ${serviceApiKey}`,
'Content-Type': 'application/json',
},
timeout: 5000,
})
if (res.statusCode >= 400) {
return response.badRequest({ error: 'Upstream request failed' })
}
return response.ok(data)
}
}
3. Use framework-level HTTP client safeguards
AdonisJS does not include a built-in HTTP client, so you likely rely on packages like axios or urllib. Configure these clients to disable redirects and set tight timeouts. Also, set a firewall or network policy that prevents outbound connections to sensitive internal endpoints.
import axios from 'axios'
const safeClient = axios.create({
maxRedirects: 0,
timeout: 8000,
validateStatus: () => true,
})
// Example call after URL validation
const resp = await safeClient.get(validatedUrl, {
headers: { Authorization: `Bearer ${serviceApiKey}` },
})
4. Monitor and log suspicious patterns
Log outbound request metadata (hostname, port, target path) without logging full URLs that may contain tokens. Use middleBrick’s CLI or dashboard to periodically scan your AdonisJS endpoints for SSRF indicators and ensure remediation aligns with findings.
Related CWEs: ssrf
| CWE ID | Name | Severity |
|---|---|---|
| CWE-918 | Server-Side Request Forgery (SSRF) | CRITICAL |
| CWE-441 | Unintended Proxy or Intermediary (Confused Deputy) | HIGH |