Saltar a contenido

Unrestricted file upload

Subida de archivos sin restricciones

Descripción

La subida de archivos sin restricciones (Unrestricted File Upload) supone un riesgo importante para las aplicaciones, pudiendo resultar en la toma de control del sistema, sobrecarga del sistema de archivos, ataques del lado del cliente o alteración (defacement). Esta vulnerabilidad puede deberse a una validación insegura de los metadatos del archivo, como en el caso de los campos HTTP Multi-part, o a una validación insegura del contenido y el tamaño, como la subida de formatos de archivo no autorizados.

Recomendación

Para mitigar los riesgos asociados con la subida de archivos sin restricciones, considere lo siguiente:

  • Validate File Type: Implemente validación del lado del servidor para garantizar que solo se permita la subida de tipos de archivos autorizados. Utilice listas blancas (whitelists) para las extensiones de archivo permitidas y rechace cualquier archivo con extensiones no permitidas. Evite depender únicamente de la validación del lado del cliente, ya que puede ser evadida.
  • Check File Content: Verifique el contenido de los archivos subidos para confirmar que coincide con su tipo de archivo. Por ejemplo, en la subida de imágenes, utilice bibliotecas o herramientas para inspeccionar los encabezados (headers) del archivo y asegurar que efectivamente sean imágenes.
  • Rename Uploaded Files: Renombre los archivos subidos para evitar que los atacantes los ejecuten adivinando el nombre del archivo. Utilice una combinación de cadenas aleatorias e identificadores únicos generados por el servidor para crear nuevos nombres para los archivos subidos.
  • Store Uploaded Files in a Secure Location: Almacene los archivos subidos fuera del directorio raíz web para prevenir el acceso directo a través de URLs. Puede emplear buckets de S3, por ejemplo.
  • Scan Uploaded Files for Malware: Emplee escáneres antivirus o antimalware para analizar los archivos subidos en busca de contenido malicioso. Implemente análisis periódicos para garantizar que no haya archivos maliciosos presentes en el servidor.
  • Monitor File Upload Activities: Implemente mecanismos de registro (logging) y monitorización para rastrear las actividades de subida de archivos. Esté atento a cualquier patrón de subida sospechoso o inusual y tome medidas inmediatas tras su detección.
const express = require('express');
const multer = require('multer');
const path = require('path');
const { v4: uuidv4 } = require('uuid');

const app = express();

// Define storage for uploaded files
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/');
  },
  filename: function (req, file, cb) {
    const ext = path.extname(file.originalname);
    cb(null, uuidv4() + ext);
  }
});

// File filter to allow only specified file extensions
const fileFilter = (req, file, cb) => {
  const allowedExtensions = ['.jpg', '.jpeg', '.png'];
  const ext = path.extname(file.originalname).toLowerCase();
  if (allowedExtensions.includes(ext)) {
    cb(null, true);
  } else {
    cb(new Error('File type not allowed!'), false);
  }
};

// Initialize multer with storage and file filter
const upload = multer({ storage: storage, fileFilter: fileFilter });

// POST endpoint for file upload
app.post('/upload', upload.single('file'), (req, res) => {
  res.send('File uploaded successfully!');
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from django.http import HttpResponseBadRequest
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
import os
from uuid import uuid4

@require_POST
def upload_file(request):
    if request.method == 'POST' and request.FILES['file']:
        file = request.FILES['file']
        allowed_extensions = ['.jpg', '.jpeg', '.png']
        ext = os.path.splitext(file.name)[1]
        if ext.lower() not in allowed_extensions:
            return HttpResponseBadRequest('File type not allowed!')
        fs = FileSystemStorage()
        filename = fs.save(str(uuid4()) + ext, file)
        return HttpResponse('File uploaded successfully!')
    else:
        return HttpResponseBadRequest('No file found!')
<?php
$uploadDir = 'uploads/';

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
    $file = $_FILES['file'];
    $allowedExtensions = array('.jpg', '.jpeg', '.png');
    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    if (!in_array($ext, $allowedExtensions)) {
        http_response_code(400);
        echo 'File type not allowed!';
        exit;
    }

    $uploadFile = $uploadDir . uniqid() . '.' . $ext;
    if (move_uploaded_file($file['tmp_name'], $uploadFile)) {
        echo 'File uploaded successfully!';
    } else {
        http_response_code(500);
        echo 'Error uploading file.';
    }
} else {
    http_response_code(400);
    echo 'No file found!';
}
?>

Enlaces

Estándares

  • CWE_TOP_25:
    • CWE_434
  • PCI_STANDARDS:
    • REQ_2_2
    • REQ_6_2
    • REQ_6_3
    • REQ_6_4
    • REQ_11_3
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_3_4
    • CC_4_1
    • CC_6_1
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5
  • HIPAA_CONTROLS:
    • SECURITY221
    • SECURITY212
    • SECURITY213