Um contador com permissão de apenas leitura poderia cancelar faturas e apagar o histórico de pagamentos na ferramenta de contabilidade de código aberto Akaunting, expondo pequenas empresas à perda silenciosa de dados. A falha foi corrigida na versão 3.2.0, mas o erro — vincular verificações de permissão a uma lista de nomes de métodos codificada de forma estática — ainda ameaça qualquer sistema que dependa de controle de acesso baseado em funções (RBAC).
Como o bug passou despercebido
A API do Akaunting valida os direitos de um usuário consultando uma lista de permissões (allowlist) de nomes de métodos. A lista cobria as operações CRUD usuais — create, read, update, delete — mas omitia vários endpoints de alteração de status:
markSentmarkCancelledmarkReceived
Como esses manipuladores (handlers) não estavam na lista, o framework nunca chamava a rotina de verificação de permissão quando eram executados. Um usuário com uma função de apenas leitura poderia enviar uma simples requisição GET para o endpoint markCancelled e o sistema a trataria como uma alteração de estado legítima.
Cancelar uma fatura faz mais do que apenas marcar o documento como inválido; também remove quaisquer registros de pagamento vinculados a essa fatura. O resultado: um usuário sem direitos de edição pode apagar o rastro financeiro de uma transação.
O que os testes mostraram
A vulnerabilidade apareceu na imagem oficial do Docker do Akaunting:
- Uma requisição PUT padrão para atualizar uma fatura retornou 403 Forbidden, confirmando que o caminho de atualização regular estava protegido.
- Uma requisição GET para o endpoint de cancelamento foi bem-sucedida sem erro de autorização, expondo a brecha.
Por que isso é importante
Demonstrações financeiras podem ser alteradas sem um rastro de auditoria claro, tornando a fraude mais difícil de detectar e os erros honestos mais difíceis de corrigir.
A correção
A versão 3.2.0 expande o mapa de permissões para incluir as ações de status anteriormente omitidas. A partir dessa versão, qualquer requisição que altere o estado de um documento — seja marcado como enviado, cancelado ou recebido — deve passar pela mesma verificação de função que uma atualização padrão. Isso restaura a expectativa de que uma função de apenas leitura realmente não possa modificar dados.
Lições para desenvolvedores
- Nunca equacione nomes de métodos com segurança. Adicionar um novo endpoint não herda proteção automaticamente; audite cada método público em busca de efeitos colaterais.
- Allowlists são tão completas quanto a própria lista. Uma lista estática de verbos "bons" deixa uma porta aberta para omissões.
- Separe a intenção do verbo HTTP. O GET deve ser apenas para leitura, mas aqui ele realizou uma alteração de estado. Restrinja mutações a POST, PUT, DELETE, PATCH.
- Automatize as verificações de cobertura de permissão. Ferramentas de análise estática podem sinalizar métodos de controller que carecem de uma chamada de autorização, detectando lacunas antes do lançamento.
- Teste com contas de privilégio mínimo. O teste baseado em Docker usou um usuário de apenas leitura; replicar tais cenários em pipelines de CI ajuda a identificar problemas semelhantes precocemente.
O que observar a seguir
A comunidade do Akaunting já lançou a versão corrigida. Os administradores devem verificar a versão de sua instância e aplicar a atualização prontamente.
Para desenvolvedores que constroem qualquer sistema baseado em funções, a lição é clara: um modelo de permissão que depende de lembrar cada ação possível é frágil por design. Declare explicitamente quais operações modificam o estado, aplique verificações no nível do framework e audite regularmente a base de código. Só assim um rótulo de "apenas leitura" poderá ser confiável para manter os registros financeiros intactos.
