Skip to content
← Back to findings
May 2026HighCVSS 8.6Target: B2B invoicing portal

Administration panel reached by rewriting a 403 in the response

The administration endpoint returned 403 with the full invoice list in the body. Rewriting the status code to 200 was enough to read it.

  • CWE-863
  • CWE-284
  • Broken Access Control
  • IDOR

Summary

The portal enforced the boundary between user and administrator entirely in the browser. The administration view asked the server for the invoice list and, on a 403 Forbidden, showed an insufficient permissions notice.

The body of that 403 carried the full invoice list. The control sat in the status code, not in what the server chose to send.

Technical details

Observed behaviour

The invoice listing request returned 403, but with a body of several hundred kilobytes:

Server response
GET /api/admin/invoices?company=[REDACTED] HTTP/2
Cookie: [UNPRIVILEGED USER SESSION]
 
HTTP/2 403 Forbidden
Content-Type: application/json
Content-Length: 412874
 
{"error":"forbidden","data":{"invoices":[ ... 3,100 records ... ]}}

Confirming the flaw

We intercepted the response and changed only the status line, leaving the body untouched. The application rendered the full panel:

Response rewritten in the proxy
HTTP/2 200 OK          # the only change
Content-Type: application/json
 
{"error":"forbidden","data":{"invoices":[ ... ]}}
 
[+] Administration panel rendered
[+] Full billing visible, including other companies

Scope of access

The company parameter was never checked against the session either. The listing was not limited to the authenticated user’s organisation:

Scope check
GET /api/admin/invoices?company=[DIFFERENT IDENTIFIER]
 
HTTP/2 403 Forbidden   -> body carrying another company’s invoices
 
[!] The company identifier was not checked against the session

We worked with two accounts provided by the client and a company identifier linked to them. We did not download or retain any third-party documents. We reported the finding the same day. We publish this analysis anonymised, with the client’s prior authorisation.

Impact

  • Administration panel access from an unprivileged account
  • Read access to the organisation’s full billing history from that same account
  • Exposure of other companies’ data on the portal, because the identifier was not checked against the session
  • Sensitive business information: billing records, contract terms and the client list
  • GDPR exposure from processing third-party billing data

Remediation

  • Authorise on the server, not in the browser. If the user has no permission, the response must not contain the resource, not even inside an error body.
  • Return empty bodies on authorisation errors. A 403 should carry a generic message and nothing else.
  • Check every identifier in the request against the session. None of them can be trusted as it arrives from the browser.
  • Review the remaining administrative endpoints for the same pattern: this kind of flaw usually lives in a shared layer.
  • Add authorisation tests to the automated suite, with an unprivileged account per role.

References

More write-ups

Check whether your administrative endpoints authorise on the server

Tell us which assets you want tested. We reply in under 24 hours.

Request an auditCall