Volver a la wiki

T4 · Handler global de excepciones sin fuga de información (Auditoría Suprema Etapa 3)

Contexto

La API de CreaRack (~509 endpoints Ninja) devolvía en respuestas 500 el mensaje técnico completo del error junto con el nombre de la clase de excepción:

{
  "error": "Unhandled API error...<ruta-interna-secreta>/opt/app/...",
  "type": "SomeException"
}

Esto exponía:

Hallazgo transversal de blueprints s105 (auditoría de seguridad): afectaba al 100% de los endpoints por ser la política global de manejo de excepciones en config/urls.py.

Decisión

Implementar un handler global de excepciones (global_exception_handler) que:

  1. En producción (DEBUG=False): Devuelve un cuerpo genérico y fijo:

    {
      "error": "Internal server error"
    }
  2. Logs del servidor: El traceback completo se registra en api.errors con contexto completo (método HTTP, path, stack).

  3. En desarrollo local (DEBUG=True): Se conservan detail (str(exc)) y type (clase) para facilitar debugging.

  4. Contrato API: El formato {"error": ...} se mantiene intacto → Sin cambios en el frontend.

Implementación

Archivo: config/urls.py / función global_exception_handler

import logging

_api_logger = logging.getLogger("api.errors")

@api.exception_handler(Exception)
def global_exception_handler(request, exc):
    """500 genérico (T4, Auditoría Suprema): el detalle del error iba al cliente..."""
    _api_logger.error("Unhandled API error on %s %s", request.method, request.path, exc_info=exc)
    body = {"error": "Internal server error"}
    if settings.DEBUG:
        body["detail"] = str(exc)
        body["type"] = exc.__class__.__name__
    return api.create_response(request, body, status=500)

Tests: tests/api/test_t4_exception_handler.py

Justificación

Relacionadas

Véase también

Subir