T09 · Insecure Skill Coding Practices
- Location
scripts/runninghub_client.py:27- Finding
RunningHub API Key Stored in a Plaintext Configuration File
- Content
View full analysis
Vulnerability Details
File Location:
scripts/runninghub_client.py, lines 27-35 and 253-258
Vulnerability Type: Plaintext credential storage with permissions inherited from the environment
Risk Level: MediumVulnerable Code
python def save_config(config: Dict[str, Any]): """Save configuration to file""" try: with open(CONFIG_FILE, "w", encoding="utf-8") as f: json.dump(config, f, indent=2, ensure_ascii=False) return True except Exception as e: print(f"❌ Config file save failed: {e}") return Falsepython if args.save_key: config = load_config() config["api_key"] = args.save_key if save_config(config): print("✅ API key saved to config file") print(f"📁 Config file: {CONFIG_FILE}") returnTechnical Analysis
The
--save-keyoperation stores the RunningHub bearer credential directly inconfig.jsonas unencrypted JSON. The application does not explicitly create the file with owner-only permissions, validate its ownership, reject symbolic links, or verify its permissions before subsequently loading it.The effective permissions are therefore determined by the process umask or by the permissions of an existing file. In a shared, broadly readable, backed-up, or otherwise compromised workspace, another local principal or process may be able to recover the credential. Writing through an existing symbolic link may also affect an unintended file when the program runs with sufficient permissions.
The documentation recommends this storage mechanism. It also presents
--api-keyas an alternative, which may expose the credential in shell history and, depending on the operating system, command-line process metadata.The key's transmission to
https://www.runninghub.aiis consistent with the Skill's declared cloud workflow functionality. The vulnerability is its local storage and input handling, not the necessary authenticated API request itse ...[truncated 1430 chars]- Remediation
View remediation
Remediation Suggestions
- Prefer an operating-system credential store or secret-management service instead of a plaintext project file.
- Retain environment-variable support and remove or discourage command-line secret arguments because command lines may be recorded in shell history or process metadata.
- If file-based persistence remains necessary, create the secret file atomically with owner-only mode
0600, rather than relying on the ambient umask. - Before reading or replacing the file, use
lstat-style checks to reject symbolic links, verify that the current user owns it, and reject group-readable or world-readable permissions. - Store secrets outside the project and shared workspace, such as in a user-specific configuration directory with mode
0700. - Ensure
config.jsonis excluded from version control, packaging, diagnostics, logs, and backups where practical. - Avoid printing secret values and redact authentication data from exceptions or debug output.
- Document credential revocation and rotation procedures. Users who previously persisted keys insecurely should rotate them after applying the fix.
- Use narrowly scoped and short-lived credentials if RunningHub supports them.
