T09 · Insecure Skill Coding Practices
- Location
manychat_cli.py:36- Finding
Unrestricted API Host Override Exposes the ManyChat Bearer Token and Subscriber Data
- Content
View full analysis
Dict[str, Any]: if not endpoint.startswith("/"): endpoint = "/" + endpoint url = f"{self.base_url.rstrip('/')}{endpoint}" body = json.dumps(payload or {}).encode("utf-8") req = request.Request( url, data=body, method="POST", headers={ "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json", "Accept": "application/json", }, ) ``` The command-line interface permits users or calling agents to supply an arbitrary destination: ```python parser.add_argument("--api-key", help=f"ManyChat API key (fallback: ${ENV_API_KEY})") parser.add_argument("--base-url", default=None, help=f"API base URL (default: {DEFAULT_BASE_URL} or ${ENV_BASE_URL})") ``` The environment variable or command-line value is accepted without scheme or hostname validation: ```python def get_client(args: argparse.Namespace) -> ManyChatClient: api_key = args.api_key or os.getenv(ENV_API_KEY) if not api_key: raise CLIError(f"Missing API key. Pass --api-key or set {ENV_API_KEY}.") base_url = args.base_url or os.getenv(ENV_BASE_URL) or DEFAULT_BASE_URL return ManyChatClient(api_key=api_key, base_url=base_url, timeout_seconds=args.timeout) ``` ### Technical Analysis The API host override is not restricted to `https://api.manychat.com`, nor is HTTPS required. Regardless of the selected origin, `ManyChatClient.call()` attaches the production ManyChat credential as an `Authorization: Bearer` header. Consequently, an attacker who can i ...[truncated 2402 chars]- Remediation
View remediation
