T09 · Insecure Skill Coding Practices
- Location
scripts/billing.py:36- Finding
SkillPay bearer API key can be transmitted to an arbitrary configured endpoint
- Content
View full analysis
None: self.api_key = api_key self.base_url = (base_url or os.getenv("SKILLPAY_BASE_URL") or "https://skillpay.me").rstrip("/") self.charge_url = charge_url or os.getenv("SKILLPAY_CHARGE_URL") if not self.charge_url: charge_path = os.getenv("SKILLPAY_CHARGE_PATH", "/charges") self.charge_url = f"{self.base_url}{charge_path}" self.session = requests.Session() def charge(self, call_name: str, amount_usdt: str, user_ref: str, idempotency_key: str) -> BillingResult: payload = { "call_name": call_name, "amount": amount_usdt, "currency": "USDT", "user_ref": user_ref, "idempotency_key": idempotency_key, "timestamp": int(time.time()), } headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json", "Idempotency-Key": idempotency_key, } delay = 0.8 for attempt in range(3): try: resp = self.session.post(self.charge_url, json=payload, headers=headers, timeout=12) ``` ### Technical Analysis The billing client accepts `SKILLPAY_BASE_URL` and `SKILLPAY_CHARGE_URL` without validating the URL scheme, hostname, port, or intended service identity. The resulting destination receives an `Authorization: Bearer` header containing the SkillPay API key. A process that can influence the environment or launch configuration can therefore redirect billing requests to an attacker-controlled host. The implementation also permits a plain HTTP destination, which cou ...[truncated 1758 chars]- Remediation
View remediation
