CreaRack-SL

Servicio MibManager (compilación pysmi, extracción OIDs, path traversal mitigation)

Propósito

MibManager (en network/services/mib_manager.py) encapsula la compilación de MIBs ASN.1 subidos con pysmi (librería de Nokia/Cisco), extrae OIDs y metadatos, y gestiona el directorio de cachés compiladas.

Funciones principales

get_mib_dir() → str

Retorna la ruta a MIB_CACHE_DIR (donde se guardan los .py compilados). Crea el directorio si no existe.

⚠️ Advertencia de seguridad (s114):

Este directorio contiene ficheros `.py` generados por pysmi a partir de MIBs
subidos por el usuario (input NO confiable). Hoy es seguro porque esos `.py`
solo se LEEN como texto (extract_oids_from_compiled), nunca se importan ni ejecutan.

NUNCA hacer import/importlib/pysnmp loadModules sobre este directorio: 
equivaldría a ejecutar código derivado de un fichero subido. Si se necesita
cargar MIBs compilados, hacerlo en un proceso/sandbox aislado.

extract_module_name(content: str) → str | None

Extrae el nombre del módulo ASN.1 del contenido del MIB (busca “MODULE DEFINITIONS ::= BEGIN”).

Retorna: nombre del módulo (ej: CISCO-SYSTEM-MIB) o None.

compile_local_mib(mib_path: str, custom_dir: str) → dict

Compila un MIB ASN.1 con pysmi.

Entrada: ruta al fichero .mib o .asn1 subido.

Retorna: dict con:

  • "success": bool
  • "output": str (stdout de pysmi)
  • "error": str (stderr si falló)
  • "compiled_path": str (ruta al .py generado, si éxito)

extract_oids_from_compiled(compiled_path: str) → list[dict]

Lee el .py compilado (como texto plano, nunca importado) y extrae OIDs.

Retorna: lista de dicts con:

{
    "name": "sysDescr",           # Nombre del OID
    "oid": "1.3.6.1.2.1.1.1",     # Notación dotted
    "type": "DisplayString",      # Tipo ASN.1
    "syntax": "OCTET STRING",     # Sintaxis
    "access": "read-only",        # Permiso SNMP
}

get_custom_mib_dir() → str

Retorna el directorio específico para MIBs custom subidos (vs. MIBs estándar incluidos en pysmi).

Path traversal fix (s114)

En upload_mib del router vendor.py, después de extraer module_name, se valida:

  1. Regex lista blanca: ^[A-Za-z0-9._-]+$

    • Rechaza: /, \, .., espacios, caracteres especiales
    • Acepta: CISCO-SYSTEM-MIB, IF-MIB.txt, foo_bar-1.0
  2. Verificación realpath:

    source_path = os.path.join(custom_dir, source_filename)
    if os.path.dirname(os.path.realpath(source_path)) != os.path.realpath(custom_dir):
        return 400, {"message": "Resolved MIB path escapes the custom MIB directory."}

Esto previene que un module_name con ../ escape del directorio permitido.

Véase también

  • [[entity—network—model—custom-mib]]
  • [[entity—network—service—mib-assistant]]
  • [[entity—network—service—vendor-registry]]
  • [[feature—network—sa3-auditoria-vendor-mib]]