T09 · Insecure Skill Coding Practices
- Location
lib/billing.ts:6- Finding
Hardcoded SkillPay API Credential Exposed in Distributed Source Code
- Content
View full analysis
Vulnerability Details
File Location:
lib/billing.ts:6-8, with credential use atlib/billing.ts:11-15,lib/billing.ts:26-37, andlib/billing.ts:53-61
Vulnerability Type: Hardcoded secret and reusable API credential
Risk Level: HighVulnerable Code
typescript const BILLING_API_URL = 'https://skillpay.me'; const BILLING_API_KEY = 'sk_97337971993cff4076fb179c0e1f42d592a89406507c603db864d6784c849bd8'; export const SKILL_ID = '3da52f24-9e3d-43bd-931d-0925e237ed93';The embedded credential is used in multiple network requests:
typescript const resp = await fetch( `${BILLING_API_URL}/api/v1/billing/balance?user_id=${encodeURIComponent(userId)}`, { headers: { 'X-API-Key': BILLING_API_KEY } } );typescript const resp = await fetch(`${BILLING_API_URL}/api/v1/billing/charge`, { method: 'POST', headers: { 'X-API-Key': BILLING_API_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ user_id: userId, skill_id: SKILL_ID, amount: 0.001, }), });typescript const resp = await fetch(`${BILLING_API_URL}/api/v1/billing/payment-link`, { method: 'POST', headers: { 'X-API-Key': BILLING_API_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ user_id: userId, amount }), });Technical Analysis
The project distributes a live-looking SkillPay API key directly in its source code. Every user who downloads the Skill can retrieve the credential without needing to execute the application. The key is then transmitted as an
X-API-Keyheader to balance, charging, and payment-link endpoints.Client-distributed API credentials cannot be treated as confidential because package recipients control the execution environment and can inspect source code or outgoing requests. An attacker can extract the key and reproduce authenticated requests independently of the Skill. The ex ...[truncated 1572 chars]
- Remediation
View remediation
Remediation Suggestions
- Immediately revoke and rotate the exposed API key because its confidentiality can no longer be assumed.
- Remove the credential from source code and repository history.
- Do not distribute a privileged billing key to clients, even through environment variables if end users control the runtime.
- Place privileged SkillPay communication behind a trusted backend. The client should authenticate as a specific user, while the backend stores the billing credential in a managed secret store.
- Scope replacement credentials to the minimum endpoints, skill, transaction amount, and environment required.
- Require server-side authorization for every
user_id; never accept an arbitrary client-supplied identifier solely because the request has the shared API key. - Add rate limits, replay protection, transaction identifiers, audit logs, and anomaly detection to charge operations.
- Fail closed on non-successful HTTP responses and validate response schemas before consuming fields such as
balanceorpayment_url. - Add automated secret scanning to source-control and release pipelines.
