/

CVE-2026-55381

Severity:

HIGH RISK

(7.1)

IDOR (CWE-639) in InvoiceShelf Estimate Conversion API

CVE-2026-55381

Deferred

Vulnerability type

Category:

Authorization Bypass / Insecure Direct Object Reference

CWE:

CWE-639

Impact:

Cross-tenant data exposure and unauthorized modification

Severity:

HIGH RISK

(7.1)

CVSS version:

3.1

Catch this CVE while code is being written

Detect vulnerable code directly in pull requests, so CVEs are fixed before merge.

Summary

InvoiceShelf contains an authorization flaw in the estimate-to-invoice conversion endpoint that checks whether an authenticated user may create invoices but does not verify access to the selected estimate. A user with the required invoice-creation ability could use an estimate belonging to another company, exposing its contents and potentially causing the original estimate to be changed or deleted.

InvoiceShelf contains an authorization flaw in the estimate-to-invoice conversion endpoint that checks whether an authenticated user may create invoices but does not verify access to the selected estimate. A user with the required invoice-creation ability could use an estimate belonging to another company, exposing its contents and potentially causing the original estimate to be changed or deleted.

Affected context

The issue occurs in multi-company InvoiceShelf deployments before the affected fix where the estimate conversion route accepts a route-bound estimate. Risk increases when an authenticated user has the ability to create invoices and the application resolves estimates without confirming that they belong to the user's company or authorized tenant. The conversion workflow may also execute company-configured actions against the original estimate.

The issue occurs in multi-company InvoiceShelf deployments before the affected fix where the estimate conversion route accepts a route-bound estimate. Risk increases when an authenticated user has the ability to create invoices and the application resolves estimates without confirming that they belong to the user's company or authorized tenant. The conversion workflow may also execute company-configured actions against the original estimate.

Exploit preconditions

  • Attack surface: Authenticated web API endpoint for estimate-to-invoice conversion - Required access: A valid account with the create-invoice ability - Trigger point: A request to the estimate conversion route containing an estimate

identifier

  • Authorization gap: The endpoint checks invoice-creation permission but does not

independently authorize access to the route-bound estimate

  • Why exploitation is possible: Estimate identifiers can resolve across company

boundaries, allowing data from another company's estimate to be incorporated

into an invoice in the attacker's company

  • Attack surface: Authenticated web API endpoint for estimate-to-invoice conversion - Required access: A valid account with the create-invoice ability - Trigger point: A request to the estimate conversion route containing an estimate

identifier

  • Authorization gap: The endpoint checks invoice-creation permission but does not

independently authorize access to the route-bound estimate

  • Why exploitation is possible: Estimate identifiers can resolve across company

boundaries, allowing data from another company's estimate to be incorporated

into an invoice in the attacker's company

Why this happens

The underlying bug is an object-level authorization failure mapped to CWE-639, Authorization Bypass Through User-Controlled Key. The controller authorizes the requested operation at the capability level but fails to enforce ownership or tenant scope for the specific estimate object selected by route-model binding. As a result, a valid permission to create an invoice is incorrectly treated as permission to read and act on any resolvable estimate.

The underlying bug is an object-level authorization failure mapped to CWE-639, Authorization Bypass Through User-Controlled Key. The controller authorizes the requested operation at the capability level but fails to enforce ownership or tenant scope for the specific estimate object selected by route-model binding. As a result, a valid permission to create an invoice is incorrectly treated as permission to read and act on any resolvable estimate.

Potential impact

  • An attacker may copy another company's line items, prices, totals, taxes, notes, currency, and customer data.
  • Sensitive customer and billing information could be disclosed across company boundaries.
  • An attacker could create invoices containing data from an unauthorized company.
  • The victim company's original estimate may be changed or deleted when configured conversion actions are processed.
  • Business records and financial workflows could be corrupted.
  • An attacker may copy another company's line items, prices, totals, taxes, notes, currency, and customer data.
  • Sensitive customer and billing information could be disclosed across company boundaries.
  • An attacker could create invoices containing data from an unauthorized company.
  • The victim company's original estimate may be changed or deleted when configured conversion actions are processed.
  • Business records and financial workflows could be corrupted.

General mitigation guidance

Mitigation generally focuses on enforcing object-level authorization at every operation boundary. Estimate retrieval and conversion should be constrained by the authenticated user's company or tenant context, rather than relying only on a general create-invoice permission. Secure-by-default patterns include scoped queries, server-side ownership checks, explicit authorization policies for both the source estimate and destination invoice, and transaction safeguards for conversion actions. User-controlled identifiers should not determine access without an independent authorization decision, and application roles should receive only the minimum cross-company privileges required.

Mitigation generally focuses on enforcing object-level authorization at every operation boundary. Estimate retrieval and conversion should be constrained by the authenticated user's company or tenant context, rather than relying only on a general create-invoice permission. Secure-by-default patterns include scoped queries, server-side ownership checks, explicit authorization policies for both the source estimate and destination invoice, and transaction safeguards for conversion actions. User-controlled identifiers should not determine access without an independent authorization decision, and application roles should receive only the minimum cross-company privileges required.

How teams detect issues like this

Detection can include static and dynamic checks for controller methods that use route-bound or user-supplied object identifiers without tenant-scoped queries. Code review should look for capability checks that are not paired with object-ownership or company-membership validation, especially in copy, export, conversion, update, and delete workflows. Automated tests can attempt cross-company object references using authorized accounts, while policy enforcement can require authorization checks for every retrieved domain object.

Detection can include static and dynamic checks for controller methods that use route-bound or user-supplied object identifiers without tenant-scoped queries. Code review should look for capability checks that are not paired with object-ownership or company-membership validation, especially in copy, export, conversion, update, and delete workflows. Automated tests can attempt cross-company object references using authorized accounts, while policy enforcement can require authorization checks for every retrieved domain object.

Sources

SourceLink
github.comgithub.com/InvoiceShelf/InvoiceShelf/commit/e432e4e62f5aa52238e3ff3fc37a0c78588eec47
github.comgithub.com/InvoiceShelf/InvoiceShelf/pull/661
github.comgithub.com/InvoiceShelf/InvoiceShelf/releases/tag/2.4.0
github.comgithub.com/InvoiceShelf/InvoiceShelf/security/advisories/GHSA-j2vg-rxqr-5vc9

Frequently asked

questions

Yes, it can be exercised through the InvoiceShelf API by an authenticated user

who has the relevant create-invoice ability. Exploitation depends on the

application accepting an estimate reference outside the user's company scope.

No administrative access is necessarily required. The important prerequisite is

an authenticated account with permission to create invoices, combined with an

estimate identifier that resolves across the tenant boundary.

Enforce object-level authorization before reading, copying, converting, changing,

or deleting an estimate. Scope lookups to the authenticated company and apply

separate authorization checks to both the source estimate and resulting invoice.

Use tenant-scoped data access by default, centralize authorization policies,

avoid treating broad capabilities as object access, and include cross-tenant

negative tests for every endpoint that accepts object identifiers.

Yes, it can be exercised through the InvoiceShelf API by an authenticated user

who has the relevant create-invoice ability. Exploitation depends on the

application accepting an estimate reference outside the user's company scope.

No administrative access is necessarily required. The important prerequisite is

an authenticated account with permission to create invoices, combined with an

estimate identifier that resolves across the tenant boundary.

Enforce object-level authorization before reading, copying, converting, changing,

or deleting an estimate. Scope lookups to the authenticated company and apply

separate authorization checks to both the source estimate and resulting invoice.

Use tenant-scoped data access by default, centralize authorization policies,

avoid treating broad capabilities as object access, and include cross-tenant

negative tests for every endpoint that accepts object identifiers.

Find out what's already
exploitable in your codebase.