T09 · Insecure Skill Coding Practices
- Location
scripts/catch_pet.py:25- Finding
Bearer Credential Can Be Transmitted Without Enforced HTTPS
- Content
View full analysis
Vulnerability Details
File Location:
scripts/catch_pet.py, lines 25–26 and 36–48
Vulnerability Type: Sensitive credential transmission without transport-security validation
Risk Level: MediumVulnerable Code
python config = { "CATCH_API_URL": os.environ.get("CATCH_API_URL") or meta.get("CATCH_API_URL") or "", "API_KEY": os.environ.get("API_KEY") or meta.get("API_KEY") or "", }python def build_request(url: str, api_key: str) -> urllib.request.Request: payload = json.dumps({"action": "catch"}).encode("utf-8") return urllib.request.Request( url, data=payload, headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", "Accept": "application/json", }, method="POST", )Technical Analysis
The Skill must send an API credential to the user-configured pet backend, so authenticated network access is necessary for its declared functionality. However,
CATCH_API_URLis accepted without validating its URL scheme, host, or redirect behavior.Consequently, an
http://URL can receive the bearer credential over an unencrypted connection. The use ofurllib.request.urlopen()also permits standard redirect handling without an explicit policy that requires redirects to remain on HTTPS and within the intended trust boundary.This does not constitute covert exfiltration: the documentation discloses the API request and bearer authentication. The vulnerability is that transport and destination safeguards are not enforced before sensitive information is transmitted.
Attack Path
- A malicious or mistaken configuration sets
CATCH_API_URLto a plaintext HTTP endpoint. Alternatively, a configured endpoint responds with a redirect toward an unintended destination. load_config()accepts the URL without scheme or destination validation.build_request()placesAPI_KEYin theAuthorization: Bearerheader ...[truncated 845 chars]
- A malicious or mistaken configuration sets
- Remediation
View remediation
Remediation Suggestions
- Parse
CATCH_API_URLwithurllib.parse.urlsplit()and require thehttpsscheme before constructing the request. - Reject URLs with missing hosts, embedded user information, fragments, malformed ports, or unsupported schemes.
- Disable automatic redirects or implement a custom redirect handler that permits a redirect only when:
- the destination still uses HTTPS;
- the destination host is explicitly trusted;
- no downgrade to HTTP occurs; and
- credentials are not forwarded across trust boundaries.
- Prefer an explicit allowlist of backend hosts when the deployment model permits it.
- Use a narrowly scoped, revocable API key that authorizes only required catch operations.
- Keep production credentials in a protected secret store or environment variable rather than
_meta.json. - Document the HTTPS-only requirement in
SKILL.mdandreferences/api.md. - Add tests confirming rejection of HTTP URLs, malformed URLs, HTTPS-to-HTTP redirects, and cross-host redirects.
Example validation:
python from urllib.parse import urlsplit def validate_api_url(url: str) -> str: parsed = urlsplit(url) if parsed.scheme.lower() != "https": raise ConfigError("CATCH_API_URL must use HTTPS.") if not parsed.hostname or parsed.username or parsed.password: raise ConfigError("CATCH_API_URL is invalid or contains embedded credentials.") if parsed.fragment: raise ConfigError("CATCH_API_URL must not contain a fragment.") return urlApply this validation before passing the URL to
build_request(), together with a restrictive redirect policy.- Parse
