T09 · Insecure Skill Coding Practices
- Location
scripts/get_weather.py:62- Finding
API Credential Disclosure Through Configuration Error Logging
- Content
View full analysis
Vulnerability Details
File Location:
scripts/get_weather.py, lines 62–66 and 109–112
Vulnerability Type: Sensitive information exposure through error messages
Risk Level: MediumVulnerable Code
python if 'app_key' not in config or 'app_secret' not in config: raise ValueError( f"Config file is missing required fields: 'app_key' and 'app_secret'\n" f"Current config: {config}" )The resulting exception is subsequently written to standard error:
python try: credentials = load_config() except (FileNotFoundError, ValueError) as e: print(f"Configuration error: {e}", file=sys.stderr) return NoneTechnical Analysis
When either
app_keyorapp_secretis absent, the validation error embeds the entire parsed configuration dictionary in its message. The caller then prints that exception to standard error.Consequently, a partially configured file containing an
app_secretbut noapp_keyexposes the secret. Any unrelated tokens, credentials, or private values stored in the same JSON object are also disclosed.Standard error may be retained by terminal capture, CI/CD logs, agent transcripts, process supervisors, centralized logging systems, or monitoring platforms. The disclosure does not require cryptographic compromise because the raw configuration values are directly serialized.
The Base64 operations elsewhere in the script are not evidence of covert exfiltration: they encode HMAC-SHA256 digests required by the documented authentication protocol. The raw
app_secretis not transmitted to the API. Reading the designated credential file and sending the app key, signatures, and requested coordinates to the hardcoded HTTPS weather endpoint are consistent with the Skill's declared functionality and do not exceed its necessary privilege scope.Attack Path
- An attacker with configuration-write access, or an accidental configuration mistake, creates a JSON configuration containing ...[truncated 1381 chars]
- Remediation
View remediation
Remediation Suggestions
Do not include configuration contents or credential values in exception messages. Report only the names of missing fields:
python required_fields = ("app_key", "app_secret") missing_fields = [ field for field in required_fields if not isinstance(config.get(field), str) or not config[field].strip() ] if missing_fields: raise ValueError( f"Config file is missing or has invalid required fields: " f"{', '.join(missing_fields)}" )Apply the following additional hardening measures:
- Validate that the parsed JSON root is an object before accessing its fields.
- Require both credentials to be non-empty strings.
- Redact secrets from every diagnostic and exception path.
- Log only minimal operational context, such as the configuration path and missing field names.
- Recommend and, where practical, verify restrictive file permissions such as
0600. - Add automated tests confirming that malformed configurations never place credential values in stdout, stderr, exceptions, or logs.
- Avoid broad exception reporting where future exception messages could contain request headers or other sensitive context.
