Media

pacioli: Un marcador de consentimiento de envío autorizaba la cancelación de documentos preexistentes designados por el invocador

  • Publicada: 09.10.2026
  • Actualizado: 15.10.2026 18:17

El aviso original ha cambiado desde que se preparó esta explicación. Consulta los datos técnicos actuales y el aviso original a continuación.

Impacto

El control de consentimiento en la capa de documentos de pacioli-guard requiere un marcador generado por un humano, de un solo uso, vinculado al documento y vinculado a la acción antes de que una credencial con API Key Scope.require_consent pueda enviar o cancelar un documento. Debido a que ERPNext realiza escrituras adicionales en documentos como consecuencia de una acción gobernada, se permite que las acciones anidadas "aprovechen" (ride) el consentimiento establecido por la acción contenedora en lugar de requerir un marcador propio.

El predicado de aprovechamiento devolvía true para cada cancelación, sin importar qué acción autorizaba el marcador contenedor. El aprovechamiento nunca alcanza consent_verdict, que es donde se aplica la vinculación entre el marcador y la acción. En consecuencia: cualquier Document.cancel() ejecutada dentro de una acción que había establecido consentimiento alcanzaba docstatus = 2 sin marcador, sin verificación de vinculación de acción, sin consumo de uso único y sin registro de auditoría de denegación.

Esto es accesible con el permiso exacto que un operador asigna documentadamente al intermediario, y la identidad del documento cancelado está controlada por el invocador:

  • Sales Invoice.on_submit (sales_invoice.py:507) llama incondicionalmente a process_asset_depreciation(), alcanzando depreciate_asset_on_sale (:1508-1516).
  • Esto itera las filas de artículos de la factura y llama a frappe.get_doc("Asset", d.asset). Sales Invoice Item.asset es un Link escribible simple sin read_only y sin fetch_from, por lo que el invocador lo proporciona en el cuerpo de la solicitud. La validación que lo restringiría se encuentra detrás de if d.is_fixed_asset: (:428-429), un campo configurado por el servidor.
  • La cadena alcanza depreciation.py:481 y luego asset_depreciation_schedule.py:215-217, que llama a current_schedule.cancel() en un docstatus == 1, enviable Asset Depreciation Schedule a través del ciclo de vida del documento (solo should_not_cancel_depreciation_entries está configurado, no ignore_validate, por lo que before_cancel sí se ejecuta y el aprovechamiento fue lo que lo admitió).

Por lo tanto, un solo marcador que autorizaba submit Sales Invoice X cancelaba un documento enviado que el humano nunca vio ni aprobó. Cancelar dicho documento revierte su efecto contable en el libro mayor.

El mismo patrón existe bajo permisos más amplios, por ejemplo Unreconcile Payment.on_submit (unreconcile_payment.py:59-64), que recorre una tabla secundaria que llena el invocador y alcanza accounts/utils.py:857/:859 gain_loss_je.cancel() en asientos de diario enviados.

Quiénes están afectados

Únicamente los entornos que optaron por el control de consentimiento: la credencial debe poseer un API Key Scope con require_consent activado. pacioli-guard es inerte para entidades principales sin dicha concesión, y el límite base de alcance de credenciales (auth_hooks) no se ve afectado por este problema.

El control de consentimiento en la capa de documentos se publicó por primera vez en 0.9.6, que es la única versión publicada en el rango afectado.

Riesgo residual declarado

Bajo una cancelación gobernada, una cancelación en cascada de un documento preexistente todavía se aprovecha. Esto es fundamental para revertir acciones (una cancelación de factura común hace que ERPNext cancele las notas de crédito/débito y los diarios generados mediante accounts_controller.py:2001-2005) y no puede restringirse sin una señal de que la cancelación en cascada es consecuencia específica del documento contenedor. Sin embargo, esa justificación no cubre todo lo admitido: al menos una instancia es dirigida por el invocador de la misma forma que el problema solucionado aquí, Asset Repair.on_cancel (asset_repair.py:215-222), que cancela un Serial and Batch Bundle nombrado mediante un enlace que el invocador completa en una tabla secundaria. pacioli-guard tampoco detecta escrituras que establecen flags.ignore_validate o que omiten por completo el ciclo de vida del documento (SQL directo, escrituras de campos con db_update/db_set); estos residuales están documentados por el proyecto y se mantienen sin cambios.

Créditos

Descubierto mediante una revisión interna el 2026-07-28 que rastreó el predicado contra el código fuente de Frappe 16.28.0 y ERPNext v16 en lugar de la documentación del proyecto. El comentario anterior en el código aseguraba que no se conocía tal mecanismo; dicha afirmación se redactó sin el barrido de código correspondiente.

Qué hacer

Parches

Corregido en 0.10.0. El mecanismo de aprovechamiento ahora discrimina según la acción contenedora: una acción de deshacer puede desencadenar más cancelaciones, pero un envío no puede desencadenar la cancelación de un documento que ya tiene un nombre asignado, ya que es una acción para la cual se podría haber solicitado aprobación humana. El sello de custodia ahora lleva la acción para la que se estableció en lugar de un simple booleano.

La actualización modifica el comportamiento. Cualquier flujo de ERPNext donde un envío desencadene una cancelación en el ciclo de vida ahora requiere un marcador de consentimiento tanto para esa cancelación como para el acto en sí. En ERPNext v16 esto incluye ventas de activos, ventas parciales de activos, notas de crédito contra ventas de activos, capitalización de reparación de activos, asignación de turnos de activos, ajuste de valor de activos y Unreconcile Payment. Para posibilitar esto, el encabezado X-Pacioli-Consent ahora acepta múltiples marcadores separados por espacios o comas; cada uno permanece vinculado a un documento y un acto, requiere un generador distinto y se consume exactamente una vez.

Mitigaciones temporales

En 0.9.6, elimine require_consent de las concesiones afectadas y dependa únicamente del límite base de alcance de credenciales, o limite las credenciales gobernadas para que no puedan enviar documentos cuyos controladores cancelen otros documentos (para ERPNext slice-one, Sales Invoice con un enlace asset en la fila de artículos es la ruta conocida). Ninguna de estas medidas sustituye la actualización.

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Python (PyPI) pacioli-guard >= 0.9.6, < 0.10.0 0.10.0

Referencias

Puntuación CVSS 5.7/10
Vector CVSS
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N
Debilidad (CWE)
CWE-863
Plataforma
Python (PyPI)
Paquete
pacioli-guard
Publicada
09.10.2026
Actualizado
15.10.2026 18:17

Fuentes y licencias · Editado o traducido por DockRay; se mantienen los derechos y las licencias de las fuentes.

OSV / GitHub Advisory Database - PYSEC-2026-4246 - PyPA Advisory Database; CC BY 4.0

OSV / GitHub Advisory Database - GHSA-3hj7-6vmj-h8v4 - CC BY 4.0

Historial de vulnerabilidades: pacioli-guard

Todas las vulnerabilidades publicadas de este paquete (Python (PyPI)), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Esta es la única vulnerabilidad conocida de este paquete.

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.