T09 · Insecure Skill Coding Practices
- Location
scripts/service/entitlement_service.py:10- Finding
Unrestricted entitlement endpoint can receive identity metadata and bearer credentials
- Content
View full analysis
Tuple[bool, str]: auth_base = (os.getenv("JIANGCHANG_AUTH_BASE_URL") or "").strip().rstrip("/") if not auth_base: return True, "" user_id = (os.getenv("JIANGCHANG_USER_ID") or "").strip() if not user_id: return False, "鉴权失败:缺少用户身份(JIANGCHANG_USER_ID)" auth_api_key = (os.getenv("JIANGCHANG_AUTH_API_KEY") or "").strip() timeout = int((os.getenv("JIANGCHANG_AUTH_TIMEOUT_SECONDS") or "5").strip()) headers = {"Content-Type": "application/json"} if auth_api_key: headers["Authorization"] = f"Bearer {auth_api_key}" payload = { "user_id": user_id, "skill_slug": skill_slug, "trace_id": (os.getenv("JIANGCHANG_TRACE_ID") or "").strip(), "context": {"entry": "main.py"}, } try: res = requests.post(f"{auth_base}/api/entitlements/check", json=payload, headers=headers, timeout=timeout) ``` ### Technical Analysis The destination for the entitlement request is taken directly from `JIANGCHANG_AUTH_BASE_URL`. The code does not parse the URL, require HTTPS, restrict the hostname to an approved entitlement service, reject embedded URL credentials, or explicitly control redirects. When `JIANGCHANG_AUTH_API_KEY` is configured, it is attached as a bearer credential to the request. The request also contains the user ID, trace ID, Skill identifier, and execution context. Consequently, any party that can influence the process environment or generated configuration can redirect this information to an arbitrary HTTP or HTTPS server. The entitlement check is invoked near the beginning of the normal `run` workflow, before business-parameter validation. Therefore, even a subsequen ...[truncated 1320 chars]- Remediation
View remediation
