CVE-2026-57562 in Readest
Summary
by MITRE • 11/04/2026
Readest is a modern, feature-rich ebook reader designed for seamless cross-platform access and an intuitive reading experience. Prior to 0.11.10, POST /api/stripe/check in apps/readest-app/src/app/api/stripe/check/route.ts accepted a client-controlled sessionId, retrieved the corresponding Stripe Checkout Session, and granted the paid plan to the authenticated caller without verifying session.metadata.userId. The createOrUpdateSubscription path then updated the plans row keyed by the caller's user identifier rather than the Checkout Session owner. Any authenticated free user with a paid active Checkout Session identifier, including one from the user's own single legitimate purchase, could replay that identifier to upgrade additional accounts without payment. This issue is fixed in version 0.11.10.
VulDB is the best source for vulnerability data and more expert information about this specific topic.
Analysis
by VulDB Data Team • 11/04/2026
The vulnerability identified in Readest prior to version 0.11.10 represents a critical business logic flaw rooted in improper verification of ownership during subscription management operations. The application utilizes Stripe Checkout Sessions to handle payments and plan upgrades, which is a standard industry practice for integrating third-party payment gateways. However, the implementation contained a significant oversight in how session data was correlated with user identities within the backend API endpoint POST /api/stripe/check located at apps/readest-app/src/app/api/stripe/check/route.ts. When this endpoint received a request containing a client-controlled sessionId parameter, it successfully retrieved the corresponding Stripe Checkout Session object from the payment provider's infrastructure. The system then proceeded to grant the paid plan privileges to the authenticated caller based solely on the presence of a valid session identifier, without performing any validation to ensure that the user initiating the request was actually the owner of that specific checkout session.
This architectural deficiency allows for an insecure direct object reference scenario where the application trusts client-supplied identifiers to determine resource ownership. Specifically, the createOrUpdateSubscription path within the codebase updates the plans database row keyed by the identifier of the currently authenticated caller rather than verifying against the userId stored in the metadata of the Stripe Checkout Session. In a secure implementation, the backend must cross-reference the user identity associated with the active session token or checkout ID to ensure that only the legitimate purchaser can activate the subscription benefits for their account. By failing to verify session.metadata.userId, the application effectively decouples the payment event from the specific user entity it was intended to benefit, creating a mechanism for privilege escalation through replay attacks.
The operational impact of this vulnerability is severe, as it enables any authenticated free user to upgrade additional accounts or themselves beyond their paid tier without making further payments. An attacker can exploit this by obtaining a valid sessionId from a legitimate purchase they have already completed and submitting that same identifier in subsequent requests against the vulnerable endpoint. Since the system only checks for the existence of a valid session rather than its ownership, it will grant premium features to any account associated with the authenticated user's credentials who submits the replayed token. This not only results in direct financial loss due to unpaid subscriptions but also undermines the integrity of the application’s licensing model and potentially exposes paid-only content or services to unauthorized users.
From a classification perspective, this vulnerability aligns with CWE-284 Improper Access Control, as it involves failing to enforce proper authorization checks on sensitive operations. It is further categorized under CWE-601 URL Redirection Through Unvalidated Redirect which can be adapted here to mean unverified object references in API logic, but more accurately fits CWE-352 Cross-Site Request Forgery if the attack vector relies on forcing a user's session context, though this specific case is better described as CWE-862 Missing Authorization. In terms of offensive security frameworks such as MITRE ATT&CK, this behavior corresponds to T1078 Valid Accounts and potentially T1534 Internal Spearphishing if used in conjunction with social engineering, but primarily it reflects a failure in Access Control enforcement during API interactions.
To mitigate this vulnerability, developers must implement strict ownership verification before processing any subscription-related actions. The backend logic should retrieve the userId from session.metadata or equivalent secure storage within the Stripe Checkout Session object and compare it against the authenticated user's identity provided by the application's authentication middleware. If these identifiers do not match exactly, the request should be rejected immediately with an appropriate error code indicating unauthorized access to that specific transaction. Additionally, implementing idempotency keys for subscription changes can prevent replay attacks even if other controls are bypassed, ensuring that each payment event is processed only once per unique user-session pair. Upgrading to version 0.11.10 or later resolves this issue by correcting the logic to properly validate session ownership before granting plan privileges.