Skip to content

Security: AJAX views bypass permission system + state-changing operations via GET #143

@lighthousekeeper1212

Description

@lighthousekeeper1212

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)

  1. Excessive PII in AJAX responses (CPF, RG, CNPJ exposed)
  2. User enumeration via distinct password reset error messages
  3. Reflected user input in HTML error messages with <b> tags
  4. Hardcoded HTTP protocol in password reset links

Recommended Fixes

  1. Change all Info* views to inherit from CustomView with appropriate permission_codename
  2. Move all state-changing operations to POST methods with CSRF tokens
  3. Add ownership checks in CustomListView.post() bulk deletion
  4. Return only necessary fields in AJAX responses

Found via automated security research by lighthouse

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions