T09 · Insecure Skill Coding Practices
- Location
payment.py:11- Finding
Hard-Coded Billing API Credential
- Content
View full analysis
Vulnerability Details
File Location:
payment.py:11-18
Vulnerability Type: Hard-coded API secret
Risk Level: HighVulnerable Code
python BILLING_API_URL = "https://skillpay.me" BILLING_API_KEY = "sk_f03aa8f8bbcf79f7aa11c112d904780f22e62add1464e3c41a79600a451eb1d2" SKILL_ID = "a2ad3e21-d3b5-4c6c-ad49-57810ceddf0b" SKILL_NAME = "dex-price-monitor" PRICE_PER_CALL = 0.01 # USDT HEADERS = { "X-API-Key": BILLING_API_KEY, "Content-Type": "application/json" }Technical Analysis
A live-format SkillPay API key is embedded directly in distributed source code. Anyone who can download, inspect, or otherwise access the Skill package can recover the credential without defeating any access control.
The credential is assigned to the global
HEADERSobject and subsequently attached to balance, charge, and payment-link requests made to the billing provider. Its placement also conflicts with_meta.json:11-14, which specifies that the API key should be supplied through theSKILLPAY_API_KEYenvironment variable:json "payment": { "api_key_env": "SKILLPAY_API_KEY", "user_id_env": "SKILLPAY_USER_ID", "required": true }The exact server-side permissions of the exposed key cannot be established through static analysis. Nevertheless, disclosure allows an attacker to authenticate as the Skill to every billing operation authorized for that key. Embedding one shared secret in every distributed copy also prevents proper per-deployment isolation and makes safe revocation and auditing difficult.
Attack Path
- An attacker obtains the publicly or internally distributed Skill package.
- The attacker opens
payment.pyand extractsBILLING_API_KEY. - The attacker constructs requests to the SkillPay billing API using the recovered value in the
X-API-Keyheader. - The attacker invokes balance, charge, payment-link, or other endpoints available to that credential.
- If server-side authorization is insufficiently scoped, ...[truncated 878 chars]
- Remediation
View remediation
Remediation Suggestions
- Revoke and rotate the exposed key immediately. Treat it as compromised even if no abuse has yet been observed.
- Load the replacement secret exclusively from the declared environment variable:
python import os BILLING_API_URL = "https://skillpay.me" BILLING_API_KEY = os.environ.get("SKILLPAY_API_KEY") if not BILLING_API_KEY: raise RuntimeError("SKILLPAY_API_KEY is required") HEADERS = { "X-API-Key": BILLING_API_KEY, "Content-Type": "application/json", }- Use a managed secret store in production rather than committing the value to source code, package metadata, examples, logs, or container images.
- Apply least privilege at the provider. Restrict the replacement credential to the required Skill ID and only the balance, charge, and payment-link operations actually needed.
- Separate credentials by environment and deployment so one leaked key cannot compromise every installation.
- Add server-side controls, including strict amount validation, Skill-ID binding, rate limits, replay protection, audit logging, and authorization checks on user identifiers.
- Review provider logs for suspicious requests made with the exposed key and investigate unauthorized charges or payment-link generation.
- Add automated secret scanning to source-control hooks and release pipelines, and block packaging when high-entropy credentials or known key prefixes are detected.
- Avoid exposing secret-bearing request details in errors or logs. Ensure HTTP debugging and exception handlers redact authentication headers.
