T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/server.py:21
- Finding
- Configurable API Base and Automatic Redirects Can Exfiltrate the Mailchimp Bearer Token<![CDATA[ ## Vulnerability Details **File Location**: `scripts/server.py`, lines 21-22, 37-40, and 61-85 **Vulnerability Type**: Bearer credential disclosure through an unvalidated network destination **Risk Level**: High ### Vulnerable Code ```python _API_BASE = os.environ.get("MAVERICK_MAILCHIMP_MCP_API_BASE", "").rstrip("/") _ACCESS_TOKEN_ENV = "MAVERICK_MAILCHIMP_MCP_ACCESS_TOKEN" ``` ```python def _api_base() -> str: if not _API_BASE: raise RuntimeError("MAVERICK_MAILCHIMP_MCP_API_BASE is required") return _API_BASE ``` ```python def _url(path: str, params: dict[str, object] | None = None) -> str: normalized_path = path if path.startswith("/") else f"/{path}" query = urllib.parse.urlencode(_clean_params(params)) url = f"{_api_base()}{normalized_path}" return f"{url}?{query}" if query else url ``` ```python def _request( access_token: str, method: str, path: str, *, params: dict[str, object] | None = None, ) -> dict[str, Any]: request = urllib.request.Request( _url(path, params), headers={ "Authorization": f"Bearer {access_token}", "Accept": "application/json", }, method=method.upper(), ) context = ssl.create_default_context(cafile=certifi.where()) try: with urllib.request.urlopen(request, timeout=30, context=context) as response: ``` ### Technical Analysis The server obtains its destination from `MAVERICK_MAILCHIMP_MCP_API_BASE` and places the OAuth bearer token in every request's `Authorization` header. `_api_base()` checks only whether the value is nonempty. It does not enforce HTTPS, validate the hostname against Mailchimp-controlled domains, reject embedded user information, restrict ports, or prevent redirects to another origin. A configurable API base is operationally useful because Mailchimp API endpoints can be data-center-specific. However, allowing an arbitrary URL exceeds the minimum network privilege require ...[truncated 2662 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the configured base with `urllib.parse.urlsplit()` before accepting it. 2. Require the `https` scheme and the default HTTPS port. 3. Allow only documented Mailchimp API hostnames. Use exact or boundary-aware validation, such as a documented data-center hostname pattern ending in `.api.mailchimp.com`; do not use a loose substring or unbounded `endswith("mailchimp.com")` check. 4. Reject URLs containing user information, fragments, unexpected paths, or encoded hostname ambiguities. 5. Disable automatic redirects for authenticated requests, or implement a redirect handler that: - allows redirects only to an explicitly approved Mailchimp origin; - rejects HTTPS-to-HTTP downgrades; - strips `Authorization` whenever the origin changes. 6. Prefer deriving the API hostname from trusted Mailchimp OAuth metadata or a validated data-center identifier rather than accepting a general-purpose URL. 7. Add tests covering malicious domains such as `api.mailchimp.com.attacker.example`, plaintext HTTP, nonstandard ports, credentials embedded in URLs, and cross-origin redirects. 8. Ensure logs and returned error objects never contain request headers or bearer-token values. ]]>
