T09 · Insecure Skill Coding Practices
- Location
skill.py:19- Finding
Configurable API Endpoint Enables Credential Disclosure, Sensitive Data Exfiltration, and SSRF
- Content
View full analysis
str: """Consistent with the base_url configuration in metadata.json: prefer runtime injection, otherwise use the SKILL_META default.""" creds = context.get("credentials") or {} ctx_cfg = context.get("config") or {} ev_cfg = event.get("config") or {} url = creds.get("base_url") or ctx_cfg.get("base_url") or ev_cfg.get("base_url") if not url: url = SKILL_META["config"]["base_url"] return url.rstrip("/") + "/" ``` The resolved URL is subsequently used for authenticated network requests: ```python url = f"{base_url}v1/legal-chat/completions" headers = { "Content-Type": "application/json", "Authorization": f"Bearer {api_key}" } payload = { "prompt": prompt, "stream": stream, "enable_network": enable_network } response = requests.post( url=url, json=payload, headers=headers, timeout=SKILL_META['config']['timeout'] ) ``` The case-analysis path sends files and structured case information to the same configurable destination: ```python url = f"{base_url}v1/case-analysis/generate" headers = {"Authorization": f"Bearer {api_key}"} if files: data = { "analysis_mode": analysis_mode, "stream": str(stream).lower(), "input": input_text or "" } files_data = [("files[]", (f["name"], f["content"], f["type"])) for f in files] response = requests.post( url=url, data=data, files=files_data, headers=headers, timeout=60 ) else: payload = {"analysis_mode": analysis_mode, "stream": stream} # The payload may subsequently contain inpu ...[truncated 3196 chars]- Remediation
View remediation
