T09 · Insecure Skill Coding Practices
- Location
SKILL.md:68- Finding
Reusable Buyer API Key Is Exposed to Untrusted Skill Code
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 68-79
Vulnerability Type: Reusable payment credential exposure
Risk Level: HighVulnerable Code
python import requests def charge_user(user_key, skill_slug="my-skill"): resp = requests.post("https://skillpay.gpupulse.dev/api/v1/pay", json={ "user_key": user_key, "skill_slug": skill_slug }) if resp.status_code == 200: return True # paid, execute skill elif resp.status_code == 402: return False # insufficient credits return FalseTechnical Analysis
The documented integration requires a buyer's reusable
sp_usr_...API key to be provided directly to skill code. The skill then transmits that credential in the JSON body of a payment request.This design violates least privilege because an untrusted or compromised skill receives the underlying account credential instead of a narrowly scoped payment authorization. The same buyer key is also documented as a bearer credential for user account endpoints elsewhere in
SKILL.md. No transaction-specific amount, expiration, nonce, user confirmation, or cryptographic binding between the authorization and a particular invocation is shown.Because the skill receives the raw credential, it can copy, log, retain, or disclose it. The code also does not demonstrate replay protection or a mechanism restricting the credential to one payment for one expected skill invocation. Although server-side protections may exist, none are documented in the audited project.
Attack Path
- A buyer registers with SkillPay and receives a reusable
sp_usr_...API key. - The buyer invokes a paid skill and supplies that key as the documented
user_keyargument. - A malicious skill, compromised skill, dependency, or logging system captures the raw key.
- The attacker retains the key after the legitimate invocation has completed.
- The attacker ...[truncated 965 chars]
- A buyer registers with SkillPay and receives a reusable
- Remediation
View remediation
Remediation Suggestions
- Do not provide the reusable account API key to third-party skill code.
- Introduce short-lived, single-use payment authorization tokens issued directly to the buyer.
- Bind each token cryptographically and server-side to the expected buyer, skill slug, exact amount, invocation identifier, and expiration time.
- Add a unique nonce and reject all replay attempts after the first successful redemption.
- Require explicit buyer approval when creating the payment authorization rather than allowing a skill to choose transaction parameters using an account credential.
- Separate account-management credentials from payment credentials and ensure payment tokens cannot access balance, deposit, registration, or withdrawal endpoints.
- Enforce server-side spending limits, rate limits, anomaly detection, revocation, and transaction notifications.
- Avoid logging credentials and redact authorization values and payment tokens from application telemetry.
- Provide credential rotation and immediate revocation mechanisms for exposed keys.
- Update the example integration so the skill receives only a scoped authorization token and never handles the buyer's reusable API key.
