T09 · Insecure Skill Coding Practices
- Location
scripts/send_email.py:136- Finding
SMTP Credentials Stored Using Reversible Base64 Encoding
- Content
View full analysis
None: """保存密码""" if KEYRING_AVAILABLE: try: keyring.set_password(self.service_name, username, password) print(f"✓ 密码已保存到 keyring (用户名: {username})") return except Exception as e: print(f"⚠️ keyring 保存失败: {str(e)},使用备用方案") # 备用方案:保存到文件 self._save_to_backup(self.password_backup_file, password) print(f"✓ 密码已保存到备用文件 (用户名: {username})") def _save_to_backup(self, backup_file: Path, content: str) -> None: """保存到备用文件(加密或编码)""" # 使用 base64 简单编码(注意:这不是加密,仅避免明文存储) import base64 encoded = base64.b64encode(content.encode('utf-8')).decode('utf-8') # 设置文件权限为仅用户可读写 backup_file.write_text(encoded) backup_file.chmod(0o600) def _read_from_backup(self, backup_file: Path) -> Optional[str]: """从备用文件读取""" if not backup_file.exists(): return None try: import base64 encoded = backup_file.read_text() return base64.b64decode(encoded).decode('utf-8') except Exception: return None ``` ### Technical Analysis When keyring is unavailable or any keyring operation raises an exception, the application automatically falls back to storing the SMTP password in `~/.send_email_password`. The fallback applies Base64 encoding, which is fully reversible and provides no cryptographic confidentiality. The code writes the file before applying mode `0600`. Consequently, the file is initially created with permissions determined by the process umask and is restricted only afterward. This creates a potential time-of-check window in which other local users or processes may be able to read the credential on systems with a permissive umask. The static pre-scan described ...[truncated 1633 chars]- Remediation
View remediation
