Skip to main content

Ghostfolio CVE-2026-47127

MEDIUM
Missing Authorization (CWE-862)
2026-08-07 security-advisories@github.com
6.5
CVSS 3.1 · Vendor: github
Share

Severity by source

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

Network callback requires authenticated session (PR:L, AV:N); subscription state is fully manipulated (I:H) with no confidentiality or availability impact.

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

Primary rating from Vendor (github).

CVSS VectorVendor: github

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

Lifecycle Timeline

2
Source Code Evidence Fetched
Aug 07, 2026 - 23:31 vuln.today
Analysis Generated
Aug 07, 2026 - 23:31 vuln.today

DescriptionCVE.org

Ghostfolio is an open source wealth management software. Prior to version 3.4.0, Ghostfolio's Stripe checkout success-URL handler at GET /api/v1/subscription/stripe/callback?checkoutSessionId=<id> retrieves the Stripe Checkout Session by ID and unconditionally grants a Premium subscription to the session's client_reference_id - without ever checking session.payment_status or session.status. There is no separate Stripe webhook endpoint with stripe-signature verification; this callback is the sole code path that creates Stripe-driven subscriptions. Any authenticated user can self-grant a 1-year Premium subscription without ever paying. Version 3.4.0 rejects sessions unless session.payment_status = 'paid' AND session.status = 'complete' (fails closed). Additionally, new unique stripeCheckoutSessionId column → a session can't be redeemed twice (race-safe via DB unique constraint).

AnalysisAI

Ghostfolio's Stripe checkout callback endpoint unconditionally grants a one-year Premium subscription to any authenticated user who supplies a valid Stripe Checkout Session ID, regardless of whether payment was completed. Versions prior to 3.4.0 retrieve the session object by ID and immediately create a subscription using the session's client_reference_id without ever asserting session.payment_status = 'paid' or session.status = 'complete'. Any registered user of an affected Ghostfolio instance can self-grant Premium access at zero cost, with no public exploit identified at time of analysis but trivial exploitability given the complete description of the missing check.

Technical ContextAI

Ghostfolio is a NestJS-based open source wealth management platform that integrates Stripe for Premium subscription billing. The vulnerable code path resides in apps/api/src/app/subscription/subscription.service.ts, where the stripeCallback handler retrieves a Stripe Checkout Session object by its ID and reads session.client_reference_id (the platform's user identifier) to create a subscription record via Prisma ORM. CWE-862 (Missing Authorization) is the root cause: the authorization gate - verifying that the Stripe session reflects a completed, paid transaction - was entirely absent. No separate Stripe webhook endpoint with HMAC stripe-signature verification existed; this callback was the sole code path for Stripe-driven subscription creation. The pre-fix schema also lacked a unique constraint on stripeCheckoutSessionId, making the endpoint vulnerable to race-condition replay. The fix in PR #6872 adds a mandatory dual-condition check (payment_status = 'paid' AND status = 'complete'), wraps subscription creation in a try-catch for Prisma unique-constraint violations (error code P2002), and adds a stripeCheckoutSessionId TEXT UNIQUE column to the Subscription table via a new Prisma migration.

Affected ProductsAI

Ghostfolio versions prior to 3.4.0 are affected, specifically deployments with Stripe subscription integration enabled. The vulnerability is in the subscription service module at apps/api/src/app/subscription/subscription.service.ts. No CPE string was provided in the input data. The authoritative vendor security advisory is published at https://github.com/ghostfolio/ghostfolio/security/advisories/GHSA-j465-x2w3-wjj8 and the fix is documented in GitHub PR #6872 at https://github.com/ghostfolio/ghostfolio/pull/6872.

RemediationAI

Upgrade to Ghostfolio version 3.4.0, which is confirmed by the vendor advisory at https://github.com/ghostfolio/ghostfolio/security/advisories/GHSA-j465-x2w3-wjj8 and implemented in PR #6872 (https://github.com/ghostfolio/ghostfolio/pull/6872). The fix enforces dual payment verification (session.payment_status = 'paid' AND session.status = 'complete') and applies a database-level unique constraint on stripeCheckoutSessionId to prevent replay. If immediate upgrade is not feasible, operators can block access to GET /api/v1/subscription/stripe/callback at the reverse proxy or firewall layer - note this will disable all Stripe-driven subscription creation until the patch is applied, which is acceptable only if Premium subscription sales can be temporarily suspended. Operators should also audit the Subscription table for records with no corresponding Stripe payment (price near zero or stripeCheckoutSessionId null on recently created rows) to identify accounts that may have already exploited this flaw. No other workaround preserves both security and subscription functionality simultaneously.

Share

CVE-2026-47127 vulnerability details – vuln.today

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