T09 · Insecure Skill Coding Practices
- Location
payment.py:11- Finding
Hard-Coded Billing API Credential Exposed in Source Code
- Content
View full analysis
Vulnerability Details
File Location:
payment.py, lines 11-18
Vulnerability Type: Hard-coded secret and reusable API credential
Risk Level: HighVulnerable Code
python BILLING_API_URL = "https://skillpay.me" BILLING_API_KEY = "sk_f03aa8f8bbcf79f7aa11c112d904780f22e62add1464e3c41a79600a451eb1d2" SKILL_ID = "a6b430c1-2bef-4879-b60b-4ad25d086577" SKILL_NAME = "football-betting-analyzer" PRICE_PER_CALL = 0.01 # USDT HEADERS = { "X-API-Key": BILLING_API_KEY, "Content-Type": "application/json" }The credential is subsequently transmitted in requests such as:
python resp = requests.post( f"{BILLING_API_URL}/api/v1/billing/charge", headers=HEADERS, json={ "user_id": user_id, "skill_id": SKILL_ID, "amount": PRICE_PER_CALL, }, timeout=10 )Technical Analysis
The billing API key is embedded directly in distributed source code. Any user who downloads, installs, or otherwise obtains the project can extract and reuse it outside the intended Skill execution context.
This also conflicts with
_meta.json, which declaresSKILLPAY_API_KEYas the expected environment-based credential source. Although requests are sent over HTTPS, transport encryption does not protect a secret already exposed in the local package.The same static credential is attached to balance, charge, and payment-link requests. The actual severity of unauthorized operations depends on the billing service's server-side authorization controls, but client-side code cannot keep a shared secret confidential.
Attack Path
- An attacker obtains a copy of the publicly distributed or locally installed Skill.
- The attacker opens
payment.pyand extractsBILLING_API_KEY. - The attacker constructs requests to the fixed SkillPay billing endpoints using the extracted value in the
X-API-Keyheader. - The attacker supplies chosen user IDs, ...[truncated 889 chars]
- Remediation
View remediation
Remediation Suggestions
-
Immediately revoke and rotate the exposed API key.
-
Remove the credential from source code and version-control history.
-
Load the key from the declared environment variable and fail closed when it is absent:
python BILLING_API_KEY = os.environ.get("SKILLPAY_API_KEY") if not BILLING_API_KEY: raise RuntimeError("SKILLPAY_API_KEY is required") -
Never distribute a privileged shared secret in client-side Skill packages. Prefer short-lived, user-scoped tokens or a trusted server-side billing proxy.
-
Restrict the replacement credential to the exact Skill ID and minimum required billing operations.
-
Enforce authorization, permitted amounts, user-to-session binding, replay protection, and rate limits on the billing server.
-
Avoid logging the credential or complete authenticated request headers.
-
Add automated secret scanning to CI and pre-commit checks.
-
Review billing logs for unauthorized use of the exposed key.
-
