T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/billing.py:16
- Finding
- Hardcoded Billing API Credential Distributed with the Skill<![CDATA[ ## Vulnerability Details **File Location**: `scripts/billing.py`, lines 16-19 **Vulnerability Type**: Hardcoded secret and insecure credential management **Risk Level**: High ### Vulnerable Code ```python BILLING_URL = "https://skillpay.me/api/v1/billing" API_KEY = os.environ.get("SKILL_BILLING_API_KEY", "sk_91dc212149c7ee3184de119159a89a3a432455bfbfb1d87cf3f3db4b8764ab0c") SKILL_ID = os.environ.get("SKILL_ID", "paythefly") HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"} ``` ### Technical Analysis The billing API credential is embedded directly in the distributed source code as the default value of `SKILL_BILLING_API_KEY`. Supplying an environment variable does not mitigate the exposure because every recipient of the package can inspect and extract the fallback credential. The credential is placed in the `X-API-Key` header used by the charge, balance, and payment-link endpoints. Although the code comments characterize it as a publisher-side, charge-only key, its actual permissions depend on server-side authorization and cannot be verified statically. At minimum, the key allows an external party to impersonate the Skill when making whatever billing requests the server permits. ### Attack Path 1. An attacker downloads or otherwise obtains the Skill package. 2. The attacker opens `scripts/billing.py` and extracts the embedded API key and default Skill ID. 3. The attacker sends requests directly to endpoints below `https://skillpay.me/api/v1/billing`, placing the extracted value in the `X-API-Key` header. 4. The attacker attempts charge, balance, or payment-link operations using chosen user identifiers. 5. Any operation permitted by the server-side scope of the exposed key executes as the publisher identity. No local code execution or system privilege escalation is needed to exploit the exposure. ### Impact Assessment The immediate impact is compromise of the billing credential and loss of publisher identity integrity. Depend ...[truncated 413 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Immediately revoke and rotate the exposed API key. 2. Remove the hardcoded fallback and require `SKILL_BILLING_API_KEY` to be supplied through a protected secret store. 3. Fail closed when the credential is absent: ```python API_KEY = os.environ.get("SKILL_BILLING_API_KEY") if not API_KEY: raise RuntimeError("SKILL_BILLING_API_KEY is required") ``` 4. Do not distribute publisher credentials in client-controlled Skill packages. Proxy billing through a trusted backend when practical. 5. Restrict the replacement credential to the minimum necessary endpoint, Skill ID, operation, amount, and rate. 6. Enforce user and Skill authorization server-side rather than trusting caller-provided identifiers. 7. Add key rotation, abuse monitoring, rate limiting, and alerts for unusual billing requests. 8. Review billing logs for use of the exposed key and invalidate any related sessions or derived credentials. ]]>
