T09 · Insecure Skill Coding Practices
- Location
scripts/yuboto_client.py:42- Finding
API Credential Disclosure Through an Unrestricted Base URL
- Content
View full analysis
str: return self.config.base_url.rstrip("/") + path def _request( self, method: str, path: str, *, params: Optional[Dict[str, Any]] = None, json_body: Optional[Dict[str, Any]] = None, ) -> Any: url = self._url(path) if params: qs = urllib.parse.urlencode({k: v for k, v in params.items() if v is not None}) if qs: url = f"{url}?{qs}" data = None if json_body is not None: data = json.dumps(json_body, ensure_ascii=False).encode("utf-8") req = urllib.request.Request( url=url, data=data, headers=self.headers, method=method.upper(), ) ``` ```python def build_client(args): api_key = args.api_key or os.getenv("OCTAPUSH_API_KEY") if not api_key: print("ERROR: missing API key. Use --api-key or OCTAPUSH_API_KEY env var.", file=sys.stderr) sys.exit(2) cfg = YubotoConfig( api_key=api_key, base_url=args.base_url, timeout=args.timeout, ) return YubotoClient(cfg) ``` ```python ap.add_argument("--base-url", default="https://api.yuboto.com") ``` ### Technical Analysis The CLI accepts an unrestricted `--base-url` value and passes it directly into `YubotoConfig`. The client then constructs every request from that value while unconditionally attaching the API credential as an `Authorization` header. No validation requi ...[truncated 1841 chars]- Remediation
View remediation
