Księgowy z uprawnieniami tylko do odczytu mógł anulować faktury i usunąć historię płatności w narzędziu do księgowości open-source Akaunting, narażając małe firmy na cichą utratę danych. Luka została naprawiona w wersji 3.2.0, ale błąd — powiązanie sprawdzania uprawnień z zakodowaną na sztywno listą nazw metod — nadal zagraża każdemu systemowi opartemu na kontroli dostępu opartej na rolach.
Jak błąd się wkradł
API Akaunting waliduje prawa użytkownika, sprawdzając listę dozwolonych (allowlist) nazw metod. Lista obejmowała standardowe operacje CRUD — create, read, update, delete — ale pominęła kilka punktów końcowych (endpoints) zmieniających status:
markSentmarkCancelledmarkReceived
Ponieważ te obsługi (handlers) nie znajdowały się na liście, framework nigdy nie wywoływał procedury sprawdzania uprawnień podczas ich działania. Użytkownik z rolą tylko do odczytu mógł wysłać zwykłe żądanie GET do punktu końcowego markCancelled, a system traktowałby to jako uprawnioną zmianę stanu.
Anulowanie faktury to coś więcej niż tylko oznaczenie dokumentu jako nieważny; powoduje ono również usunięcie wszelkich rekordów płatności powiązanych z tą fakturą. Skutek: użytkownik bez uprawnień do edycji może wymazać ślad finansowy transakcji.
Co wykazały testy
Luka pojawiła się w oficjalnym obrazie Docker Akaunting:
- Standardowe żądanie PUT w celu aktualizacji faktury zwracało 403 Forbidden, co potwierdzało, że standardowa ścieżka aktualizacji była chroniona.
- Żądanie GET do punktu końcowego anulowania zakończyło się sukcesem bez błędu autoryzacji, ujawniając lukę.
Dlaczego to ma znaczenie
Sprawozdania finansowe mogą zostać zmienione bez wyraźnego śladu audytowego, co utrudnia wykrycie oszustw i naprawienie uczciwych błędów.
Poprawka
Wersja 3.2.0 rozszerza mapę uprawnień o wcześniej pominięte akcje statusowe. Od tej wersji każde żądanie zmieniające stan dokumentu — czy to oznaczenie jako wysłany, anulowany czy otrzymany — musi przejść taką samą weryfikację roli, jak standardowa aktualizacja. Przywraca to oczekiwanie, że rola tylko do odczytu rzeczywiście nie może modyfikować danych.
Lekcje dla programistów
- Nigdy nie utożsamiaj nazw metod z bezpieczeństwem. Dodanie nowego punktu końcowego nie oznacza automatycznego dziedziczenia ochrony; należy audytować każdą publiczną metodę pod kątem efektów ubocznych.
- Listy dozwolonych są tak kompletne, jak sama lista. Statyczna lista „dobrych” czasowników pozostawia otwarte drzwi dla przeoczeń.
- Oddzielaj intencję od czasownika HTTP. Metoda GET służy do odczytu, ale tutaj dokonała zmiany stanu. Ogranicz mutacje do metod POST, PUT, DELETE, PATCH.
- Automatyzuj sprawdzanie zakresu uprawnień. Narzędzia do analizy statycznej mogą flagować metody kontrolera pozbawione wywołania autoryzacji, wyłapując luki przed wdrożeniem.
- Testuj z kontami o najniższych uprawnieniach. Test oparty na Dockerze wykorzystał użytkownika z uprawnieniami tylko do odczytu; replikowanie takich scenariuszy w potokach CI pozwala na wczesne wykrycie podobnych problemów.
Na co zwrócić uwagę w przyszłości
Społeczność Akaunting wydała już poprawioną wersję. Administratorzy powinni sprawdzić wersję swojej instancji i niezwłocznie zastosować aktualizację.
Dla programistów budujących jakiekolwiek systemy oparte na rolach wniosek jest jasny: model uprawnień, który zależy od pamiętania o każdej możliwej akcji, jest z założenia kruchy. Jawnie deklaruj, które operacje zmieniają stan, wymuszaj sprawdzanie na poziomie frameworka i regularnie audytuj kod źródłowy. Tylko wtedy można ufać, że etykieta „tylko do odczytu” faktycznie chroni nienaruszalność zapisów finansowych.
