Skip to main content

InvoiceShelf CVE-2026-55383

| EUVDEUVD-2026-101610 HIGH
Improper Authorization (CWE-285)
2026-10-14 security-advisories@github.com
8.2
CVSS 3.1 · Vendor: github
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Obtain a valid or expired EmailLog token link
  2. Delivery
    Submit token to /customer/invoices|estimates|payments JSON route
  3. Exploit
    Server skips mailable_type and expiry checks
  4. Execution
    Colliding numeric id resolves foreign document
  5. Impact
    Disclose another company's invoice/estimate/payment and mark it viewed

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V8 - Authorization Authorization verification
MITRE ATT&CK

1 technique across 1 tactic: Defense Evasion

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

Exploitation targets the public customer routes GET /customer/invoices/{email_log:token}, GET /customer/estimates/{email_log:token}, and GET /customer/payments/{email_log:token} on InvoiceShelf versions prior to 2.4.0. The attacker must possess a valid EmailLog token (an email link issued to any customer); no account authentication is required (PR:N). Two concrete conditions enable abuse: (1) the JSON handlers resolve $emailLog->mailable_id without verifying mailable_type, so a token issued for one document type discloses a different company's document when numeric identifiers COLLIDE across tenants - this id collision is the limiting factor and is opportunistic, not attacker-controlled; (2) the JSON handlers did not enforce EmailLog::isExpired, so an EXPIRED token remains usable - this path needs only an old link and is fully reliable. The view handlers additionally require the target invoice/estimate to be in STATUS_SENT or STATUS_DRAFT to flip it to 'viewed' and send a notification. The flaw requires no special server configuration; it affects default deployments of vulnerable versions.

Impact

This is a genuine authorization flaw (CWE-285), not a high-CVSS-but-low-risk artifact, but the real-world priority is moderated by product footprint and exploitation prerequisites. The CVSS 3.1 vector (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N, base 8.2) correctly reflects remote, unauthenticated, network-reachable access to the public customer JSON routes, with high confidentiality impact (cross-company document disclosure) and low integrity impact (a mismatched invoice/estimate can be marked 'viewed' and trigger a notification email). No availability impact. There is no EPSS score, no CISA KEV listing, and no public POC supplied in the input, so exploitation likelihood signals are absent - meaning no public exploit identified at time of analysis. One nuance to flag explicitly: the most impactful variant (disclosing a DIFFERENT company's document) requires the attacker's own valid EmailLog token's numeric mailable_id to collide with another company's document id across mailable types, which is opportunistic/targeted rather than reliably controllable - this makes AC arguably higher than AC:L for that path. The simpler, fully reliable path is reuse of an EXPIRED token on the JSON routes (the handlers did not enforce EmailLog::isExpired), which needs only possession of a now-expired link. Net: a real authorization/IDOR-class issue worth prompt patching, but absent KEV/EPSS/POC signals and given a niche self-hosted product, it is a moderate operational priority rather than an emergency.

Exploit ScenarioDerived

An attacker who legitimately received an InvoiceShelf email link (an EmailLog token) replays it after expiry, or substitutes it against the customer JSON routes, and retrieves invoice, estimate, or payment data. Where the token's numeric mailable_id collides with another tenant's document id, the response discloses a different company's financial document; requesting an estimate/invoice can also flip its status to 'viewed' and dispatch a notification email. No public exploit code is referenced in the input, and the network-reachable, low-complexity, unauthenticated routes make the expired-token reuse path straightforward.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.4% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Oct 14, 2026

InvoiceShelf installs prior to 2.4.0 leak other customers' invoices, estimates, and payment PDFs through the public customer-portal token routes, because the EmailLog token is resolved by numeric mailable_id without checking mailable_type and the JSON handlers never enforce EmailLog::isExpired. An unauthenticated remote attacker holding any legitimate emailed customer link (PR:N, no account needed) can therefore retrieve a document belonging to a different company when numeric identifiers collide across tenants, or keep using an already-expired link indefinitely on the JSON routes GET /customer/invoices/{email_log:token}, GET /customer/estimates/{email_log:token}, and GET /customer/payments/{email_log:token}; the view handlers can additionally flip a mismatched invoice or estimate to 'viewed' and trigger a notification email. Rated CVSS 8.2 (C:H, I:L) as a genuine improper-authorization flaw (CWE-285), though the cross-tenant variant is opportunistic and gated by id collisions while the expired-token variant is fully reliable; no public exploit code has been identified at time of analysis and the issue is fixed in version 2.4.0.

RemediationAI

Upgrade to InvoiceShelf 2.4.0, which is the vendor-released patch and the version that replaces the raw mailable_id lookups with the type-checked $emailLog->mailable relation and applies abort_if($emailLog->isExpired(), 403, 'Link Expired.') on every PDF, JSON, and view path; the fix is delivered via commit 5839d8385debf379644f55e773639e1c7e673163 (PR 662) and documented in GHSA-73q7-2953-8gvx. If an immediate upgrade is not possible, compensating controls should target the two abuse paths: invalidate or delete stale EmailLog rows and shorten the token validity window in configuration so expired links stop resolving, accepting that this breaks legitimate customer links already sent by email and requires re-sending them; and treat any customer-portal token as cross-tenant sensitive by rate-limiting or IP-restricting the /customer/invoices, /customer/estimates, and /customer/payments token routes at the reverse proxy, at the cost of added friction for genuine customers and possible false positives on shared NAT egress. Because the cross-tenant disclosure depends on numeric id collisions, avoid sequential per-tenant id ranges as a stopgap only if a backport is infeasible, and monitor web logs for repeated token-route requests across unrelated company ids or for tokens older than the configured expiry, since such patterns indicate active probing. Note that no vendor-released patch exists for versions below 2.4.0 other than the upstream commit itself, so the 2.4.0 upgrade is the authoritative remediation.

Affected VersionsENISA

InvoiceShelf < 2.4.0

Affected Packages

euvd invoiceshelf fix: 2.4.0

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

InvoiceShelf is a Laravel (PHP) invoicing application whose EmailLog model stores outbound email links using a polymorphic pair: a numeric mailable_id plus a mailable_type discriminator. The vulnerable controllers (EstimatePdfController, InvoicePdfController, PaymentPdfController) performed Estimate::find($emailLog->mailable_id), Invoice::find($emailLog->mailable_id), and Payment::find($emailLog->mailable_id) directly, discarding the mailable_type, so the type check that polymorphic relations normally provide was bypassed; this is a classic CWE-285 improper authorization defect in which the object reference is not validated against the principal's entitlement. Two distinct weaknesses follow: documents are looked up in the wrong table whenever a token issued for one mailable type is paired with a colliding numeric id in another company's records, and the expiry guard (EmailLog::isExpired) was applied only on some paths, leaving the JSON handlers able to serve expired links. The upstream fix replaces the raw find() with the $emailLog->mailable relation plus abort_unless($doc instanceof Invoice|Estimate|Payment, 404) and abort_if($emailLog->isExpired(), 403, 'Link Expired.'), which both restores type enforcement and makes expiry checks uniform across PDF/JSON/view handlers. Attack surface is network-reachable with no authentication or user interaction (AV:N/AC:L/PR:N/UI:N), and the confidentiality impact is high because full invoice, estimate, or payment documents-billing details, customer data, amounts-are returned; integrity impact is limited to status transitions (SENT/DRAFT to VIEWED) and the resulting notification email, hence I:L.

Know when the next one hits your stack

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (github) PRIMARY 8.2 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N
vuln.today AI 8.2 HIGH

Public token routes are unauthenticated and network-reachable (AV:N/PR:N/UI:N); the reliable expired-token reuse path keeps AC:L; cross-company disclosure gives C:H and status/notification writes give I:L, no availability impact.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N

Primary rating from Vendor (github).

CVSS VectorVendor: github

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
Low
Availability
None

Lifecycle Timeline

2
Patch available
Oct 14, 2026 - 21:18 EUVD
CVE Published
Oct 14, 2026 - 20:17 cve.org
HIGH 8.2

DescriptionCVE.org

InvoiceShelf is an open-source web & mobile app that helps track expenses, payments and create professional invoices and estimates. Prior to version 2.4.0, InvoiceShelf public customer invoice, estimate, and payment routes use an EmailLog token's numeric mailable_id without verifying mailable_type, and the JSON handlers do not enforce EmailLog::isExpired. A token issued for one document type can therefore disclose a different company's document when numeric identifiers collide, and an expired token can remain usable on the JSON routes GET /customer/invoices/{email_log:token}, GET /customer/estimates/{email_log:token}, and GET /customer/payments/{email_log:token}. View handlers can also mark a mismatched invoice or estimate as viewed and send a notification. This issue is fixed in version 2.4.0.

Technical POC Analysis

Improper authorization (CWE-285) implemented as a type-confusion on Laravel route-model-bound tokens.

Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.

Executive ViewAI

Why It Matters

InvoiceShelf deployments prior to 2.4.0 can expose customer invoices, estimates, and payment PDFs across customer accounts because the customer-portal token routes may resolve emailed links to the wrong tenant or continue accepting expired links. The issue is unauthenticated and rated CVSS 8.2, so any organization hosting an affected instance faces potential confidentiality loss and cross-tenant trust erosion, with no public exploit identified at time of analysis. Leadership should treat this as a customer-data protection and compliance risk, especially where InvoiceShelf is internet-facing or used by multiple client organizations.

Business Impact: High
Compensating Controls

No vendor-released patch identified at time of analysis; interim mitigations include restricting or disabling the public token routes GET /customer/invoices/{email_log:token}, GET /customer/estimates/{email_log:token}, and GET /customer/payments/{email_log:token} where possible, invalidating and reissuing emailed customer links, monitoring those endpoints for anomalous or cross-tenant access, limiting InvoiceShelf exposure to trusted networks, and applying virtual patching/WAF rules while awaiting a vendor fix.

Threat Intelligence Overview

EPSS Score
0.4%
Top 65% exploitable
Prevalence
Low
niche self-hosted open-source invoicing app, limited enterprise footprint
Data Quality
6 sources
Confidence: High

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC No
EPSS 0.4%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Scheduled
Exploitation
Poc
System Exposure· derived
Open
Automatable
Yes
Human Impact
High
Technical Impact
Partial

Priority Score

41
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +41
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy