T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/fetch_unseen.py:16
- Finding
- Credential Redirection Through Independently Overridable IMAP Host<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch_unseen.py`, lines 16–47 and 112–113 **Vulnerability Type**: Credential exposure through unsafe configuration-source mixing **Risk Level**: High ### Vulnerable Code ```python _env_host = os.environ.get("IMAP_HOST", "").strip() _env_port = os.environ.get("IMAP_PORT", "").strip() _env_username = os.environ.get("IMAP_USERNAME", "").strip() _env_password = os.environ.get("IMAP_PASSWORD", "").strip() _env_maxchars = os.environ.get("IMAP_MAX_BODY_CHARS", "").strip() if _env_username and _env_password: # Credentials supplied entirely via env — no config file required IMAP_HOST = _env_host or "imap.gmail.com" IMAP_PORT = int(_env_port) if _env_port else 993 USERNAME = _env_username PASSWORD = _env_password MAX_CHARS = min(int(_env_maxchars) if _env_maxchars else 2000, 2000) else: config_path_env = os.environ.get("EMAIL_CONFIG_PATH", "").strip() if config_path_env: config_path = Path(config_path_env).expanduser() else: config_path = Path.home() / ".config" / "gmail-summarize" / "config.json" cfg = json.loads(config_path.read_text()) email_cfg = cfg.get("email", {}) IMAP_HOST = _env_host or email_cfg.get("imapHost", "imap.gmail.com") IMAP_PORT = int(_env_port) if _env_port else int(email_cfg.get("imapPort", 993)) USERNAME = _env_username or email_cfg.get("imapUsername", "") PASSWORD = _env_password or email_cfg.get("imapPassword", "") ``` The resulting values are used directly for authentication: ```python client = imaplib.IMAP4_SSL(IMAP_HOST, IMAP_PORT) client.login(USERNAME, PASSWORD) ``` ### Technical Analysis The host, port, username, and password are resolved independently from environment variables and the fallback configuration file. Consequently, an environment-provided `IMAP_HOST` can be combined with credentials read from the user's configuration file. The script does not validate or allowlist th ...[truncated 1839 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Resolve the endpoint and credentials atomically from a single configuration source. Do not combine an environment-selected host with credentials loaded from a file. 2. If environment credentials are incomplete, reject the configuration rather than silently filling missing values from disk. 3. For this Gmail-specific Skill, allowlist `imap.gmail.com` by default. 4. Require explicit user approval for custom IMAP providers and store the approved endpoint together with the corresponding credentials. 5. Validate the normalized hostname and reject IP literals, unexpected ports, malformed hostnames, and unapproved endpoints. 6. Consider binding credentials to an expected server identity in a secret manager rather than accepting independent generic environment variables. 7. Ensure authentication failures and exceptions never print credential values. ]]>
