Back to skill

Security audit

In-App Purchases

Security checks for vulnerabilities and agentic risk

Overview

The skill is transparently about in-app purchases, but some examples could lead developers to implement insecure subscription and entitlement handling.

Install only if you are prepared to review and harden any copied payment code. In particular, verify webhooks before changing entitlements, validate Apple and Google purchase state completely, keep secret API keys server-side, minimize stored receipts and subscriber data, and add retention, access-control, and audit policies.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
revenuecat.md:193
Finding

Unauthenticated RevenueCat Webhook Permits Forged Entitlement Events

Content
View full analysis
{ 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
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
analytics.md:254
Finding

Unauthenticated Analytics Webhook Allows Subscription Data Poisoning

Content
View full analysis
{ await db.events.insert({ event_type: req.body.type, user_id: req.body.app_user_id, product_id: req.body.product_id, price: req.body.price, currency: req.body.currency, timestamp: new Date(req.body.event_timestamp_ms) }); res.sendStatus(200); }); ``` ### Technical Analysis The data-warehouse endpoint inserts request fields directly into the event store without authenticating the sender. It does not validate event types, identifiers, numeric values, currency codes, timestamp ranges, or request sizes. No idempotency or replay control is shown. Parameterized behavior of `db.events.insert` cannot be determined from the documentation, so database injection is not confirmed. However, analytics poisoning is directly supported by the example: arbitrary callers can supply records that the application stores as RevenueCat events. The absence of error handling can also result in unreliable webhook delivery behavior or unhandled asynchronous errors when invalid values reach the database. ### Attack Path 1. An attacker locates the public `/revenuecat/webhook` endpoint. 2. The attacker sends fabricated subscription events with arbitrary user IDs, product IDs, prices, currencies, and timestamps. 3. The endpoint performs no sender authentication and inserts the supplied fields. 4. The attacker repeats the request or submits extreme values because no replay prevention, rate limiting, or bounds validation is shown. 5. Reporting systems consume the forged records and produce corrupted revenue, conversion, churn, or cohort metrics. ### Impact Assessment An attacker could poison business analytics, falsely inflate or reduce reported revenue, associate events with arbitrary us ...[truncated 261 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
server.md:19
Finding

Apple Transaction Identifier Is Consumed from an Unverified JWS

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
server.md:150
Finding

Android Subscription Verification Unconditionally Reports Valid Status

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (13)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The analytics examples explicitly log subscription-related events and business-sensitive values such as product identifiers, price, and LTV estimates, but provide no guidance on consent, data minimization, retention, or compliance obligations. In an in-app purchases skill, this omission is material because implementers are likely to copy these patterns directly, potentially resulting in privacy-law violations or overcollection of user-linked monetization data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The webhook example stores externally supplied subscription event data, including app_user_id and purchase metadata, directly into a database without any warning about privacy handling, validation, or least-data collection. In this skill context, subscription webhooks commonly map to identifiable users, so implementers may persist regulated personal and revenue data unnecessarily or insecurely, increasing privacy and breach exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

This markdown file includes instructions for initiating purchases and restoring prior purchases, which can affect billing state and account entitlements. The document does not include any warning or disclosure to users/developers that these actions may trigger charges, restore paid content, or require clear user communication in the app.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The purchase example uses a product ID string check to decide whether an item is a subscription and then routes subscriptions to buyNonConsumable, which is incorrect and brittle. This can cause developers to implement broken purchase flows, mis-handle entitlement types, and potentially grant or deny paid access incorrectly despite later server verification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The webhook example grants, extends, and revokes access based solely on the request body, without verifying webhook authenticity or integrity. If copied as-is, an attacker could forge webhook requests to manipulate subscription state, leading to unauthorized premium access or account disruption.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The REST API examples demonstrate use of a secret API key and subscriber identifiers but omit critical guidance that these credentials must be kept server-side, never embedded in client apps, and handled as sensitive customer data. In a payments/subscriptions context, readers may copy this pattern into insecure environments, risking API key exposure, unauthorized entitlement changes, or subscriber data disclosure.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · revenuecat.md (reported line 236)May include surrounding context.

bash
# Get subscriber info
curl -X GET \
  "https://api.revenuecat.com/v1/subscribers/$USER_ID" \
  -H "Authorization: Bearer $SECRET_API_KEY"

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · revenuecat.md (reported line 237)May include surrounding context.

bash
# Get subscriber info
curl -X GET \
  "https://api.revenuecat.com/v1/subscribers/$USER_ID" \
  -H "Authorization: Bearer $SECRET_API_KEY"

# Grant entitlement (promo)

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · revenuecat.md (reported line 242)May include surrounding context.

bash
# Get subscriber info
curl -X GET \
  "https://api.revenuecat.com/v1/subscribers/$USER_ID" \
  -H "Authorization: Bearer $SECRET_API_KEY"

# Grant entitlement (promo)

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · revenuecat.md (reported line 249)May include surrounding context.

bash
# Get subscriber info
curl -X GET \
  "https://api.revenuecat.com/v1/subscribers/$USER_ID" \
  -H "Authorization: Bearer $SECRET_API_KEY"

# Grant entitlement (promo)

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · server.md (reported line 29)May include surrounding context.

md
const token = generateAppStoreJWT();
  
  const response = await axios.get(
    `https://api.storekit.itunes.apple.com/inApps/v1/transactions/${transactionId}`,
    { headers: { Authorization: `Bearer ${token}` } }
  );

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · server.md (reported line 59)May include surrounding context.

md
const token = generateAppStoreJWT();
  
  const response = await axios.get(
    `https://api.storekit.itunes.apple.com/inApps/v1/transactions/${transactionId}`,
    { headers: { Authorization: `Bearer ${token}` } }
  );

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The guidance explicitly recommends storing raw receipts for dispute resolution but provides no safeguards around minimization, encryption, retention, or access control. Purchase receipts and tokens can contain sensitive transactional identifiers and may be replayable or privacy-relevant if leaked, so telling implementers to store them without handling guidance creates a real security and privacy risk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.