Średnia

pacioli: Znacznik zgody na zatwierdzenie zezwalał na anulowanie istniejących dokumentów wskazanych przez wywołującego

  • Ujawniono: 09.10.2026
  • Aktualizacja: 15.10.2026 18:17

Komunikat źródłowy zmienił się od przygotowania tego objaśnienia. Sprawdź aktualne dane techniczne i oryginalny komunikat poniżej.

Wpływ

Bramka zgody na poziomie dokumentów w pacioli-guard wymaga utworzonego przez człowieka, jednorazowego, powiązanego z dokumentem oraz powiązanego z czynnością znacznika, zanim poświadczenie z uprawnieniem API Key Scope.require_consent będzie mogło zatwierdzić lub anulować dokument. Ponieważ ERPNext wykonuje dalsze operacje zapisu dokumentów w następstwie kontrolowanej czynności, czynności zagnieżdżone mogą skorzystać z uprawnień (ride) zgody ustanowionej przez czynność nadrzędną, zamiast wymagać własnego znacznika.

Predykat przejęcia zgody zwracał true dla każdego anulowania, niezależnie od tego, na jaką czynność zezwalał znacznik nadrzędny. Przejęcie zgody nigdy nie dociera do consent_verdict, gdzie wymuszane jest powiązanie znacznika z czynnością. W rezultacie każda operacja Document.cancel() wykonana wewnątrz czynności z ustaloną zgodą docierała do docstatus = 2 bez znacznika, bez weryfikacji powiązania czynności, bez jednorazowego zużycia i bez wpisu audytowego o odmowie.

Ścieżka ta jest dostępna przy dokładnie takim zestawie uprawnień, jaki zgodnie z dokumentacją operator nadaje brokerowi, a tożsamość anulowanego dokumentu jest kontrolowana przez wywołującego:

  • Sales Invoice.on_submit (sales_invoice.py:507) bezwarunkowo wywołuje process_asset_depreciation(), dochodząc do depreciate_asset_on_sale (:1508-1516).
  • Następnie iteruje po wierszach pozycji faktury i wywołuje frappe.get_doc("Asset", d.asset). Pole Sales Invoice Item.asset jest zwykłym zapisywalnym Link bez read_only oraz fetch_from, więc wywołujący przekazuje je w treści żądania. Walidacja, która mogłaby je ograniczyć, znajduje się za if d.is_fixed_asset: (:428-429), polem ustawianym przez serwer.
  • Łańcuch dociera do depreciation.py:481, a następnie do asset_depreciation_schedule.py:215-217, co wywołuje current_schedule.cancel() na docstatus == 1, zatwierdzalnym Asset Depreciation Schedule poprzez cykl życia dokumentu (ustawione jest tylko should_not_cancel_depreciation_entries, a nie ignore_validate, w związku z czym before_cancel jest wywoływane i to przejęcie zgody umożliwiło wykonanie operacji).

W ten sposób jeden znacznik autoryzujący submit Sales Invoice X anulował zatwierdzony dokument, którego człowiek nigdy nie widział ani nie zatwierdził. Anulowanie takiego dokumentu cofa jego skutki w księdze głównej.

Taki sam schemat występuje przy szerszych uprawnieniach, na przykład Unreconcile Payment.on_submit (unreconcile_payment.py:59-64), który iteruje po tabeli podrzędnej wypełnianej przez wywołującego i osiąga accounts/utils.py:857/:859 gain_loss_je.cancel() na zatwierdzonych wpisach do księgi (Journal Entries).

Kogo dotyczy problem

Problem dotyczy wyłącznie instancji, które włączyły bramkowanie zgód: poświadczenie musi posiadać API Key Scope z ustawionym require_consent. Mechanizm pacioli-guard jest nieaktywny dla podmiotów bez takiego uprawnienia, a bazowy zakres poświadczeń (auth_hooks) pozostaje nienaruszony.

Bramka zgody na poziomie dokumentu została po raz pierwszy opublikowana w 0.9.6, co stanowi jedyną wydaną wersję w podatnym zakresie.

Ryzyko rezydualne

W ramach kontrolowanego anulowania kaskadowe anulowanie wcześniej istniejącego dokumentu nadal korzysta z przejętej zgody. Jest to kluczowe dla operacji cofania (zwykłe anulowanie faktury powoduje, że ERPNext anuluje powiązane noty kredytowe/debetowe i wpisy księgowe za pośrednictwem accounts_controller.py:2001-2005) i nie może zostać zawężone bez sygnału, że kaskadowe anulowanie jest bezpośrednią konsekwencją dokumentu nadrzędnego. Uzasadnienie to nie obejmuje jednak wszystkich dopuszczanych przypadków: co najmniej jeden z nich może być kontrolowany przez wywołującego w taki sam sposób jak omawiana podatność: Asset Repair.on_cancel (asset_repair.py:215-222), który anuluje Serial and Batch Bundle wskazany przez powiązanie (Link) uzupełniane w tabeli podrzędnej. pacioli-guard nie obejmuje również operacji zapisu ustawiających flags.ignore_validate ani takich, które całkowicie pomijają cykl życia dokumentu (bezpośredni SQL, zapisy pól przez db_update/db_set); te ograniczenia są opisane w dokumentacji projektu i pozostają niezmienione.

Podziękowania

Podatność wykryta podczas wewnętrznego przeglądu bezpieczeństwa w dniu 2026-07-28, który przeanalizował predykat w kodzie źródłowym frappe 16.28.0 i ERPNext v16, a nie tylko w dokumentacji projektu. Poprzedni komentarz w kodzie zakładał brak takich mechanizmów, co sformułowano bez wcześniejszej analizy źródeł.

Co trzeba zrobić

Poprawki

Problem naprawiono w 0.10.0. Mechanizm przejęcia zgody rozróżnia teraz czynność nadrzędną: operacja cofania może kaskadowo wywołać kolejne cofnięcia, ale operacja zatwierdzenia (submit) nie może kaskadowo wywołać anulowania dokumentu posiadającego już nazwę, ponieważ jest to czynność, o zatwierdzenie której można było poprosić człowieka. Znacznik nadzoru przechowuje teraz czynność, dla której został ustanowiony, zamiast prostej wartości logicznej.

Aktualizacja zmienia zachowanie systemu. Każdy przepływ ERPNext, w którym zatwierdzenie prowadzi kaskadowo do anulowania w cyklu życia, wymaga teraz znacznika zgody na to anulowanie oprócz znacznika na samą czynność. W ERPNext v16 obejmuje to sprzedaż środków trwałych, sprzedaż częściowej ilości środków trwałych, notę kredytową do sprzedaży środka trwałego, kapitalizację naprawy środka trwałego, alokację zmianową środka trwałego, korektę wartości środka trwałego oraz Unreconcile Payment. Aby to umożliwić, nagłówek X-Pacioli-Consent akceptuje teraz wiele znaczników rozdzielonych spacjami lub przecinkami; każdy pozostaje powiązany z jednym dokumentem i jedną czynnością, wymaga innego wystawcy i jest zużywany dokładnie raz.

Obejścia

W wersji 0.9.6 należy usunąć require_consent z uprawnień i polegać wyłącznie na bazowych ograniczeniach poświadczeń lub ograniczyć nadzorowane poświadczenia, aby nie mogły zatwierdzać dokumentów, których kontrolery anulują inne dokumenty (dla ERPNext slice-one znaną ścieżką jest Sales Invoice z wypełnionym powiązaniem asset w wierszu pozycji). Żadne z tych obejść nie zastępuje aktualizacji.

Czego dotyczy

Kliknij technologię, aby zobaczyć wszystkie dotyczące jej podatności.

PlatformaPaczkaPodatne wersjePoprawka w wersji
Python (PyPI) pacioli-guard >= 0.9.6, < 0.10.0 0.10.0

Odnośniki

Ocena CVSS 5.7/10
Wektor CVSS
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N
Słabość (CWE)
CWE-863
Platforma
Python (PyPI)
Paczka
pacioli-guard
Ujawniono
09.10.2026
Aktualizacja
15.10.2026 18:17

Źródła i licencje · Redakcja lub tłumaczenie: DockRay. Zachowano prawa źródeł i obowiązujące licencje.

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

Historia podatności: pacioli-guard

Wszystkie opisane podatności tej paczki (Python (PyPI)), od najnowszej. Widać, czy to jednorazowa wpadka, czy paczka, której trzeba pilnować.

To jedyna znana podatność tej paczki.

Dowiedz się, które podatności dotyczą Twojej aplikacji

Po podłączeniu integracji DockRay i włączeniu raportowania oprogramowania DockRay porównuje zgłoszone wersje komponentów ze znanymi podatnościami i powiadamia o potwierdzonych dopasowaniach. Zakres zależy od obsługiwanej technologii i dostępnych biuletynów.

Podłącz swoją aplikację
Newsletter DockRay

Bezpieczeństwo aplikacji w Twojej skrzynce

Najważniejsze podatności, konkretne zalecenia i praktyczne wskazówki dla Twoich aplikacji. Wybierz technologie i śledź to, co ma znaczenie dla Twojego projektu.

  • Codzienne zestawienie nowych podatności, także krytycznych.
  • Powiadomienia o ważnych aktualizacjach.
  • Praktyczne porady o bezpieczeństwie i monitoringu aplikacji.

Pozostaw puste, aby otrzymywać informacje o wszystkich technologiach.

Zapis jest bezpłatny. Wypiszesz się jednym kliknięciem w wiadomości.