Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
enforcement-coverage — Encuentra rutas de API con autorización más débil que sus homólogas. Recuperó CVE-2026-45316 del código fuente. Incluye los resultados negativos. | Kitploit
Herramientas/GitHubGitHub/arian-gogani/enforcement-coverage
Análisis Estático de Código (SAST)Análisis de VulnerabilidadesAnálisis de CódigoPruebas de PenetraciónDevSecOpsSeguridad de APIs
GitHubarian-gogani/enforcement-coverage

enforcement-coverage

Encuentra rutas de API con autorización más débil que sus homólogas. Recuperó CVE-2026-45316 del código fuente. Incluye los resultados negativos.

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Ver Repositorio
hace 15h 48mAún no revisado

Cobertura de Cumplimiento

Encuentra rutas de API que llevan un control de autorización más débil que el de sus rutas hermanas.

Encontró CVE-2026-45316 en Open WebUI solo a partir del código fuente, sin conocimiento de avisos de seguridad:

root@kitploit:~
[MISMATCH] POST /notes/{id}/pin  (notes.py:pin_note_by_id)
  3/3 comparable write operations on note require has_access(write);
  this route requires only has_access(read)

    POST   /notes/{id}/update          has_access(write)
    POST   /notes/{id}/access/update   has_access(write)
    DELETE /notes/{id}/delete          has_access(write)

En 2.568 rutas en cinco bases de código en producción produjo 4 hallazgos. Dos eran reales. Este README explica ambos números.

La idea

Una gran clase de errores de autorización no es una comprobación rota. Es una comprobación faltante o debilitada, en una ruta cuyas hermanas todas la hicieron bien.

Portainer autorizó cuatro endpoints de plantillas hermanos y no al quinto. Signal K limitó la tasa de inicio de sesión HTTP pero no la de WebSocket. La ruta de pin de notas de Open WebUI mutaba una nota mientras comprobaba el permiso de lectura, cuando cualquier otra mutación de notas comprobaba escritura.

Siempre la misma forma:

root@kitploit:~
✓ ✓ ✓ ✓ ✗

El repositorio ya contiene la regla. Una ruta la rompió. Así que reconstruya la regla desde el código e informe la excepción. Sin archivo de política, sin configuración, sin anotaciones. El conjunto de prueba son las propias rutas hermanas.

Ejecutarlo

root@kitploit:~
python3 enforcement_coverage.py /path/to/repo
python3 enforcement_coverage.py /path/to/repo --density
python3 enforcement_coverage.py /path/to/repo --json

Python 3.10+, sin dependencias. Solo FastAPI.

Los veredictos son MISSING, MISMATCH, PRESERVED, UNKNOWN. UNKNOWN se abstiene y nunca se informa.

Qué hace

Extracción. Resuelve controles a partir de la firma Depends(), el decorador dependencies=[], dependencias a nivel de enrutador, cuerpos de función, funciones envoltorio y listas de clases de permisos.

La extracción del cuerpo es esencial. En Open WebUI, 216 de 608 manejadores llevan la comprobación decisiva dentro de la función:

root@kitploit:~
if user.role != 'admin' and not await AccessGrants.has_access(
    user_id=user.id, resource_type='note',
    resource_id=note.id, permission='write', db=db,
):
    raise HTTPException(status_code=403)

La clase de operación proviene de lo que el manejador hace con el recurso, no del verbo HTTP. POST /notes/{id}/chat es un POST que lee una nota.

Clasificación de vocabulario. Dos valores en una misma familia de control no forman necesariamente una escala de fuerza:

root@kitploit:~
has_access             {read, write}                      LEVEL
ensure_flow_permission {create,delete,execute,read,write}  ACTION
has_permission         {features.notes, workspace.tools}   SCOPE

Solo los vocabularios LEVEL admiten comparación de fuerza. Comparar FlowAction.CREATE con un WRITE dominante produjo seis falsos positivos en Langflow antes de que esto se corrigiera.

Filtro de dirección. Solo se informan desviaciones hacia un control menos restrictivo. Ser más estricto que el precedente no es una vulnerabilidad.

Lo que encontró

Dos verdaderos positivos.

POST /notes/{id}/pin en Open WebUI — CVE-2026-45316.

Un hallazgo adicional es una asimetría de permisos en Netflix Dispatch: POST /{incident_id}/resources usa IncidentViewPermission mientras que seis operaciones de escritura hermanas usan IncidentEditPermission. IncidentViewPermission devuelve True para cualquier incidente no restringido; IncidentEditPermission requiere administrador, comandante o reportero. El manejador pone en cola la creación de tickets y grupos sin más comprobaciones.

No se informó porque no hay lugar donde informarlo: el repositorio fue archivado por Netflix el 3 de septiembre de 2025 y es de solo lectura, no tiene SECURITY.md, el informe privado de vulnerabilidades está deshabilitado para repositorios archivados, y Dispatch está explícitamente fuera de alcance en el programa de recompensas de Netflix. Publicarlo aquí es el único canal de divulgación restante. Es de gravedad baja — requiere un miembro autenticado de la organización y afecta solo a incidentes no restringidos — y el proyecto ya no se mantiene.

Dos falsos positivos. POST /tools/{id}/valves/user/update escribe la configuración de válvulas propia del usuario y legítimamente solo necesita lectura sobre la herramienta — el objetivo de la mutación es una entidad diferente al sujeto de autorización. Y una ruta de base de conocimiento de Langflow donde el control de la ruta hermana no es necesario.

Por qué en su mayoría no funciona

Esta es la parte útil.

La densidad no predice hallazgos

Danswer tiene un 95,9 % de cobertura de control y produjo cero hallazgos con un 80,7 % de UNKNOWN. Su vocabulario es require_permission('basic_access'), ('manage_connectors') — un espacio de nombres de capacidades, no una escala de fuerza. No se puede decir que manage_connectors sea más débil que read_connectors.

Lo que predice hallazgos es una llamada de permiso con ámbito de recurso y un argumento de fuerza ordenado, como has_access(resource, read|write). Una de cada cinco bases de código tenía eso.

Cada base de código necesitó una extracción diferente

Cinco patrones en cinco repositorios. Cada uno requirió trabajo de extracción antes de que el análisis pudiera ejecutarse en absoluto.

UNKNOWN nunca bajó del 72 %

En cualquier repositorio, bajo cualquier configuración. La mayoría de las rutas no pertenecen a una familia de rutas hermanas de tres o más con un control consistente.

Defectos encontrados al ejecutarlo contra código real

Ninguno de estos fue anticipado de antemano.

  1. La autorización vive en los cuerpos de función, no en Depends()
  2. Las rutas llevan varias familias de control a la vez
  3. El verbo HTTP no es la clase de operación
  4. Los patrones de autorización difieren según el repositorio
  5. Los vocabularios de acción no son escalas de fuerza
  6. Ser más estricto que el precedente no es una vulnerabilidad
  7. El vocabulario clasificado solo a partir de precedentes oculta familias de un solo valor
  8. Los helpers de validación que lanzan 422 no son autorización
  9. Las funciones envoltorio ocultan el control real
  10. Los patrones de listas de clases de permisos requieren división de nombres
  11. Aflojar familias hermanas aumentó los hallazgos 7,5 veces y redujo la precisión del 50 % al 13 %
  12. Una ruta con un control suficiente diferente no carece de uno
  13. aplicación equivalente implementada en línea en lugar de como dependencia — sin resolver

El defecto 13 es el interesante. Las rutas de recomendación de etiquetas de Dispatch carecen del CaseViewPermission que llevan sus hermanas. Pero ese permiso devuelve True para cualquier caso no restringido, y el servicio ya comprueba visibility == restricted en línea. Los caminos son equivalentes. Detectar eso requiere análisis de equivalencia semántica, no estructura.

Evaluación honesta

El mecanismo funciona. Recuperó un CVE publicado y una brecha de autorización no reportada a partir del código fuente, con conjuntos de prueba auditables, usando solo información disponible antes de que el commit vulnerable se fusionara.

El rendimiento es de aproximadamente un hallazgo por cada 1.000 rutas, y necesita una arquitectura que una de cinco bases de código sustanciales tenía.

Útil como herramienta de auditoría para una base de código con un vocabulario de permisos con ámbito de recurso. No es, según esta evidencia, un escáner de propósito general.

Trabajos previos

La detección estática de vulnerabilidades de control de acceso mediante la inferencia de supuestos implícitos se remonta a USENIX Security 2011. ACMiner extrajo comprobaciones de autorización en el middleware de Android. Semgrep incluye detección impulsada por IA orientada a la autorización faltante y reportó una precisión del 61 % en una evaluación de un cliente. OWASP publica una hoja de referencia de Pruebas de Regresión de Autorización cuyo enfoque recomendado es mantener una matriz Actor × Recurso × Acción a mano.

Este es un enfoque limitado y determinista: recuperar solo lo que prueban las rutas hermanas, abstenerse en caso contrario.

Licencia MIT.

Descargar herramienta
repositoriorutascontroladashallazgos
LiteLLM80887.1%0
Danswer / Onyx65395.9%0
Open WebUI52997.2%2
Netflix Dispatch29136.1%1
Langflow28747.4%1
repositoriopatrón
Open WebUIAccessGrants.has_access(resource_type=, permission=)
Langflowensure_<resource>_permission(user, Action.X)
LiteLLMcomparación de rol sobre user_api_key_dict.user_role
Netflix DispatchDepends(PermissionsDependency([CaseEditPermission]))
Danswerrequire_permission('basic_access')