Volver a la wiki

Auditoría Suprema s105: Blueprints / Auto-Plan (22 fixes)

Resumen

Tercera tanda de la Auditoría Suprema (iniciativa de seguridad exhaustiva). Ámbito: Map Editor (blueprints) y Auto-Plan de IA. Se arreglan los 22 hallazgos confirmados de una vez (decisión de Edu: “definitivo, todo de una vez”).

Alcance: 7 ALTA + 12 MEDIA + 3 BAJA (de 61 hallazgos crudos → 40 únicos → 22 confirmados). Datos: auditoria-suprema/blueprints.md / .json.


Hallazgos y Fixes (SEGURIDAD)

1. Broken Access Control sistemático (~25 endpoints)

Problema: NINGÚN endpoint del módulo blueprints aplicaba gate de permisos. Un usuario con rol readonly podía:

Fix:

Endpoints afectados:


2. Fuga cross-tenant en views.py

Problema: El Map Editor usaba Organization.objects.first() como fallback para usuarios sin organización asignada, mostrándoles blueprints y racks del primer tenant de la BD. Violación de RLS (multi-tenancy).

Fix: Eliminado el fallback. Ahora render vacío si el usuario no tiene org (o se redirige correctamente en el frontend).


3. AI Brain prompt global compartido entre tenants

Problema: Los endpoints /prompt/save y /prompt/reset escribían un único fichero global (prompts/blueprint_analyst.md) que pisaban todos los tenants. Si una org lo editaba, afectaba a todas.

Fix: Resemantización del modelo AIPrompt:

Subcomponentes:


4. Auto-Plan: validación de subida + atomicidad + audit

Problema: Falta de límite de tamaño, transacciones incompletas, sin registro de auditoría, errores exponen str(exc).

Fix:


5. Decompression bomb en Auto-Plan

Problema: AutoPlanService.get_image_scaling() abría la imagen sin validar tamaño (Pillow tiene MAX_IMAGE_PIXELS desactivado a nivel de proceso).

Fix:


Hallazgos y Fixes (CORRECTNESS)

6. GET /{bp_id}/placements roto (500)

Problema: Endpoint llamaba a BlueprintService.list_placements(), método inexistente → AttributeError en cada llamada.

Fix: Implementado en el service (excluye racks en papelera).


7. delete_rack_total hard-deleteaba

Problema: El endpoint /delete de racks hacía rack.delete() (hard-delete irreversible), saltándose el sistema de papelera del resto del producto.

Fix: Ahora rack.soft_delete(). El rack desaparece de los mapas pero es recuperable desde la papelera (papelera/restore).


8. Racks soft-deleted seguían en el mapa

Problema: Los listados de placements no filtraban rack__deleted_at, así que racks en papelera seguían apareciendo.

Fix: Filtro rack__deleted_at__isnull=True en:


9. duplicate_element sin validación JSON

Problema: Duplicar una anotación hacía json.loads(annot.data) sin try/except → 500 ante data corrupta.

Fix: Try/except con mensaje 400 claro:

try:
    data = json.loads(annot.data) if annot.data else {}
except (json.JSONDecodeError, TypeError):
    return 400, {"message": "Annotation data is corrupt and cannot be duplicated"}

10. create_annotation permitía data JSON inválida

Problema: Una data string no-JSON se persistía sin validar → corrompe la BD.

Fix: Validación previa:

try:
    json.loads(annot_data)
except (json.JSONDecodeError, TypeError):
    return 400, {"message": "Field 'data' must be valid JSON"}

11. N+1 en /list (blueprints)

Problema: Un COUNT por blueprint en el listado de filtros → N+1.

Fix: annotate(Count("placements")) (una sola query agregada).


12. Endpoints de edición operaban sobre blueprints en papelera

Problema: Filtro deleted_at__isnull=True faltaba en varios endpoints de edición.

Fix: Agregado a:


Tests

Archivo nuevo: tests/api/test_blueprints_security.py (10 tests)

Verificación local: 54 tests verdes (blueprints + racks security + tenant isolation), ruff + django check limpios.


Fuera de tanda (documentado)

Dos decisiones de follow-up (misma sesión, PR distinto):

  1. Handler global de errores (config/urls.py): filtrar str(exc) en todos los exception handlers (transversal a ~509 endpoints). Decisión aparte porque es global y podría tener side effects. Por ahora algunos endpoints siguen exponiendo mensajes internos.

  2. Auto-Plan asíncrono: convertir magic_import_blueprint() a async (Celery / tarea en background). Toca frontend del Map Editor (UX: spinner, polling). PR propio.

Datos detallados: auditoria-suprema/blueprints.md (hallazgos + análisis) y .json (estructura de datos).


Impacto para devs


Véase también

Subir