Een accountant met alleen-lezen-rechten kon facturen annuleren en de betalingsgeschiedenis wissen in de open-source boekhoudtool Akaunting, waardoor kleine bedrijven werden blootgesteld aan onopgemerkt gegevensverlies. De kwetsbaarheid is opgelost in versie 3.2.0, maar de fout — het koppelen van machtigingscontroles aan een hardgecodeerde lijst met methodenamen — vormt nog steeds een bedreiging voor elk systeem dat vertrouwt op rolgebaseerde toegangscontrole.
Hoe de bug erdoorheen glipte
De API van Akaunting valideert de rechten van een gebruiker door een allowlist met methodenamen te raadplegen. De lijst bevatte de gebruikelijke CRUD-bewerkingen — create, read, update, delete — maar miste verschillende endpoints die de status wijzigen:
markSentmarkCancelledmarkReceived
Omdat deze handlers niet op de lijst stonden, riep het framework de routine voor machtigingscontrole nooit aan wanneer ze werden uitgevoerd. Een gebruiker met een alleen-lezen-rol kon een eenvoudige GET-aanvraag doen naar het markCancelled-endpoint en het systeem zou dit behandelen als een legitieme statuswijziging.
Het annuleren van een factuur doet meer dan het document als ongeldig markeren; het verwijdert ook alle betalingsgegevens die aan die factuur zijn gekoppeld. Het resultaat: een gebruiker zonder bewerkingsrechten kan het financiële spoor van een transactie uitwissen.
Wat de tests lieten zien
De kwetsbaarheid kwam naar voren in de officiële Docker-image van Akaunting:
- Een standaard PUT-aanvraag om een factuur bij te werken, gaf 403 Forbidden terug, wat bevestigde dat het reguliere updatepad beschermd was.
- Een GET-aanvraag naar het annulerings-endpoint slaagde zonder autorisatiefout, wat het gat blootlegde.
Waarom dit belangrijk is
Financiële overzichten kunnen worden gewijzigd zonder een duidelijk auditspoor, waardoor fraude moeilijker te ontdekken is en eerlijke fouten moeilijker te herstellen zijn.
De oplossing
Versie 3.2.0 breidt de machtigingskaart uit om de eerder weggelaten statusacties op te nemen. Vanaf die release moet elke aanvraag die de status van een document wijzigt — of deze nu als verzonden, geannuleerd of ontvangen wordt gemarkeerd — door dezelfde rolverificatie gaan als een standaard update. Dit herstelt de verwachting dat een alleen-lezen-rol daadwerkelijk geen gegevens kan wijzigen.
Lessen voor ontwikkelaars
- Koppel methodenamen nooit aan veiligheid. Het toevoegen van een nieuw endpoint betekent niet automatisch dat het beschermd is; controleer elke publieke methode op neveneffecten.
- Allowlists zijn slechts zo volledig als de lijst zelf. Een statische lijst met "goede" werkwoorden laat de deur open staan voor onoplettendheden.
- Scheid de intentie van het HTTP-werkwoord. GET is bedoeld voor alleen-lezen, maar hier voerde het een statuswijziging uit. Beperk mutaties tot POST, PUT, DELETE, PATCH.
- Automatiseer controles op de dekking van machtigingen. Statische analyse-tools kunnen controller-methoden markeren die een autorisatie-aanroep missen, zodat hiaten worden ontdekt voordat ze worden uitgebracht.
- Test met accounts met minimale rechten. De Docker-gebaseerde test gebruikte een alleen-lezen-gebruiker; het repliceren van dergelijke scenario's in CI-pipelines brengt soortgelijke problemen vroegtijdig aan het licht.
Waar u op moet letten
De community van Akaunting heeft de gepatchte versie al uitgebracht. Beheerders moeten de versie van hun instantie controleren en de update onmiddellijk toepassen.
Voor ontwikkelaars die een rolgebaseerd systeem bouwen, is de les duidelijk: een machtigingsmodel dat afhankelijk is van het onthouden van elke mogelijke actie, is inherent kwetsbaar. Declareer expliciet welke operaties de status wijzigen, dwing controles af op frameworkniveau en controleer de codebase regelmatig. Pas dan kan een "alleen-lezen"-label erop worden vertrouwd dat financiële gegevens intact blijven.
