Summary
Security audit of djangoSIGE identified 8 vulnerabilities (2 HIGH, 6 MEDIUM). The application has a well-designed permission system (CheckPermissionMixin via CustomView), but 8 AJAX views bypass it entirely by inheriting from plain View instead of CustomView.
Key Findings
1. AJAX Views Bypass Permission System (HIGH)
Files: cadastro/views/ajax_views.py, vendas/views/ajax_views.py, compras/views/ajax_views.py, vendas/views/pagamento.py
All 8 AJAX "Info" views inherit from Django's View instead of CustomView, completely bypassing CheckPermissionMixin:
InfoCliente(View) — leaks client PII (CPF, CNPJ, RG, addresses)
InfoFornecedor(View) — leaks supplier PII
InfoEmpresa(View) — leaks company data
InfoTransportadora(View) — leaks carrier data
InfoProduto(View) — leaks product pricing/stock
InfoVenda(View) — leaks sales order details
InfoCompra(View) — leaks purchase order details
InfoCondicaoPagamento(View) — leaks payment conditions
Any authenticated user with zero permissions can query any record by ID.
2. State-Changing Operations via GET (MEDIUM)
Files: vendas/views/vendas.py, compras/views/compras.py, financeiro/views/lancamento.py
13 state-changing operations (cancel orders, create invoices, receive stock) use GET requests instead of POST, making them vulnerable to CSRF-via-link attacks:
CancelarPedidoVendaView.get() — cancels sales orders
FaturarPedidoVendaView.get() — invoices orders (creates financial entries + modifies stock)
ReceberPedidoCompraView.get() — receives purchase orders
3. Bulk Deletion Without Ownership (MEDIUM)
File: base/custom_views.py:54-60
CustomListView.post() allows bulk deletion by ID with only permission check, no ownership verification. Any user with delete permission can delete any record of that type.
Other Findings (MEDIUM)
- Excessive PII in AJAX responses (CPF, RG, CNPJ exposed)
- User enumeration via distinct password reset error messages
- Reflected user input in HTML error messages with
<b> tags
- Hardcoded HTTP protocol in password reset links
Recommended Fixes
- Change all
Info* views to inherit from CustomView with appropriate permission_codename
- Move all state-changing operations to POST methods with CSRF tokens
- Add ownership checks in
CustomListView.post() bulk deletion
- Return only necessary fields in AJAX responses
Found via automated security research by lighthouse
Summary
Security audit of djangoSIGE identified 8 vulnerabilities (2 HIGH, 6 MEDIUM). The application has a well-designed permission system (
CheckPermissionMixinviaCustomView), but 8 AJAX views bypass it entirely by inheriting from plainViewinstead ofCustomView.Key Findings
1. AJAX Views Bypass Permission System (HIGH)
Files:
cadastro/views/ajax_views.py,vendas/views/ajax_views.py,compras/views/ajax_views.py,vendas/views/pagamento.pyAll 8 AJAX "Info" views inherit from Django's
Viewinstead ofCustomView, completely bypassingCheckPermissionMixin:InfoCliente(View)— leaks client PII (CPF, CNPJ, RG, addresses)InfoFornecedor(View)— leaks supplier PIIInfoEmpresa(View)— leaks company dataInfoTransportadora(View)— leaks carrier dataInfoProduto(View)— leaks product pricing/stockInfoVenda(View)— leaks sales order detailsInfoCompra(View)— leaks purchase order detailsInfoCondicaoPagamento(View)— leaks payment conditionsAny authenticated user with zero permissions can query any record by ID.
2. State-Changing Operations via GET (MEDIUM)
Files:
vendas/views/vendas.py,compras/views/compras.py,financeiro/views/lancamento.py13 state-changing operations (cancel orders, create invoices, receive stock) use GET requests instead of POST, making them vulnerable to CSRF-via-link attacks:
CancelarPedidoVendaView.get()— cancels sales ordersFaturarPedidoVendaView.get()— invoices orders (creates financial entries + modifies stock)ReceberPedidoCompraView.get()— receives purchase orders3. Bulk Deletion Without Ownership (MEDIUM)
File:
base/custom_views.py:54-60CustomListView.post()allows bulk deletion by ID with only permission check, no ownership verification. Any user with delete permission can delete any record of that type.Other Findings (MEDIUM)
<b>tagsRecommended Fixes
Info*views to inherit fromCustomViewwith appropriatepermission_codenameCustomListView.post()bulk deletionFound via automated security research by lighthouse