Implementación Segura
Marco de Seguridad Integral para la Carga de Archivos
Estrategia de Implementación Segura
graph TD
A[Solicitud de Carga de Archivo] --> B[Validación en el Cliente]
B --> C[Validación en el Servidor]
C --> D[Comprobación del Tipo de Archivo]
D --> E[Verificación del Tamaño del Archivo]
E --> F[Sanitizar el Nombre de Archivo]
F --> G[Generar un Nombre de Archivo Único]
G --> H[Almacenar en una Ubicación Segura]
H --> I[Establecer Permisos Estrictos]
Técnicas de Validación
Enfoque de Validación Multicapa
| Capa de Validación |
Mecanismo de Seguridad |
| Cliente |
Comprobaciones básicas iniciales |
| Servidor |
Validación exhaustiva |
| Sistema de Archivos |
Controles de permisos estrictos |
Implementación Segura en Python
import os
import magic
from werkzeug.utils import secure_filename
import uuid
class FileUploadHandler:
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'pdf'}
MAX_FILE_SIZE = 5 * 1024 * 1024 ## 5MB
@staticmethod
def validate_file(file_stream):
## Comprobar el tamaño del archivo
file_stream.seek(0, os.SEEK_END)
file_size = file_stream.tell()
file_stream.seek(0)
if file_size > FileUploadHandler.MAX_FILE_SIZE:
raise ValueError("Archivo demasiado grande")
## Comprobar el tipo de archivo usando magic
file_type = magic.from_buffer(file_stream.read(2048), mime=True)
file_stream.seek(0)
tipos_mime_permitidos = {
'image/jpeg',
'image/png',
'application/pdf'
}
if file_type not in tipos_mime_permitidos:
raise ValueError("Tipo de archivo inválido")
@staticmethod
def secure_filename(filename):
## Sanitizar el nombre de archivo
nombre_sanitizado = secure_filename(filename)
## Generar un nombre de archivo único
nombre_unico = f"{uuid.uuid4()}_{nombre_sanitizado}"
return nombre_unico
@staticmethod
def save_file(file_stream, upload_directory):
## Validar el archivo
FileUploadHandler.validate_file(file_stream)
## Generar un nombre de archivo seguro
nombre_archivo = FileUploadHandler.secure_filename(file_stream.filename)
## Ruta completa del archivo
ruta_archivo = os.path.join(upload_directory, nombre_archivo)
## Guardar el archivo con permisos restringidos
with open(ruta_archivo, 'wb') as f:
f.write(file_stream.read())
## Establecer permisos de archivo seguros
os.chmod(ruta_archivo, 0o640)
Refuerzo de Permisos de Archivos en Bash
#!/bin/bash
## Directorio de carga seguro
UPLOAD_DIR="/var/www/uploads"
## Crear el directorio con permisos restringidos
mkdir -p "$UPLOAD_DIR"
chown www-data:www-data "$UPLOAD_DIR"
chmod 750 "$UPLOAD_DIR"
## Establecer ACL predeterminada para nuevos archivos
setfacl -d -m u::rw,g::r,o::- "$UPLOAD_DIR"
Consideraciones de Seguridad Avanzadas
Estrategias de Almacenamiento de Archivos
- Almacenar archivos cargados fuera del directorio raíz web
- Usar volúmenes de almacenamiento separados
- Implementar registro de accesos
Permisos Recomendados
- Usuario del servidor web: Lectura/Escritura
- Grupo: Solo lectura
- Otros: Sin acceso
Recomendaciones de Seguridad de LabEx
En LabEx, destacamos un enfoque holístico para la seguridad de la carga de archivos, combinando múltiples capas de validación y controles de acceso estrictos.
Principios Clave de Implementación
- No confiar nunca en la entrada del usuario.
- Validar en múltiples capas.
- Usar bibliotecas seguras.
- Implementar modelos de permisos estrictos.
- Registrar y monitorear las actividades de carga de archivos.