T09 · Insecure Skill Coding Practices
Error
- Location
- revenuecat.md:193
- Finding
- Unauthenticated RevenueCat Webhook Permits Forged Entitlement Events<![CDATA[ ## Vulnerability Details **File Location**: `revenuecat.md`, lines 193-220 **Vulnerability Type**: Unauthenticated webhook with authorization-sensitive side effects **Risk Level**: High ### Vulnerable Code ```javascript app.post('/revenuecat/webhook', (req, res) => { const event = req.body; switch (event.type) { case 'INITIAL_PURCHASE': grantAccess(event.app_user_id, event.product_id); break; case 'RENEWAL': extendAccess(event.app_user_id); break; case 'CANCELLATION': // User cancelled - will expire at period end markWillExpire(event.app_user_id); break; case 'EXPIRATION': revokeAccess(event.app_user_id); break; case 'BILLING_ISSUE': sendPaymentFailedEmail(event.app_user_id); break; case 'SUBSCRIBER_ALIAS': // User IDs merged break; } res.sendStatus(200); }); ``` ### Technical Analysis The example trusts `req.body` and performs entitlement and account lifecycle operations without authenticating the request as originating from RevenueCat. It also lacks schema validation, event replay protection, idempotency enforcement, and reconciliation with RevenueCat's authenticated API. Because `event.type`, `event.app_user_id`, and `event.product_id` are attacker-controlled for an unauthenticated request, a caller can select the operation and target account. These fields directly reach functions that grant, extend, alter, or revoke access. Webhook authentication is necessary even when the endpoint uses HTTPS. TLS protects traffic in transit but does not prove that an arbitrary caller is RevenueCat. ### Attack Path 1. An attacker discovers or predicts the public `/revenuecat/webhook` endpoint. 2. The attacker submits a forged JSON request such as an `INITIAL_PURCHASE` event containing a selected application user ID and product ID. 3. The handler accepts the request without verifying an authorization secret or trusted signature. 4. The handler ...[truncated 762 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Configure a high-entropy RevenueCat webhook authorization value and require it on every request. 2. Compare authentication values using a timing-safe comparison and reject unauthorized requests before parsing or processing event data. 3. Validate requests against a strict schema: - Permit only supported event types. - Validate user, product, application, environment, and event identifiers. - Enforce field lengths and expected data types. 4. Record RevenueCat's unique event identifier and reject duplicate or replayed events. 5. Make entitlement transitions idempotent and transactionally update the database. 6. Reconcile high-impact changes with RevenueCat's authenticated REST API before granting or revoking access. 7. Apply request-body size limits, rate limiting, audit logging, and safe error handling. 8. Do not log webhook authorization secrets, full receipts, or unnecessary subscriber identifiers. ]]>
