T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/omnium_client.py:107
- Finding
- Bearer API Key Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:20-33`; `scripts/omnium_client.py:107-110` **Vulnerability Type**: Credential exposure through process arguments and command history **Risk Level**: High ### Vulnerable Code ```markdown **Usage:** ```bash python3 scripts/omnium_client.py --api-key "YOUR_KEY" contacts --action [lookup|create|update] --email "user@example.com" [other options] ``` **Examples:** * "Find the contact for john@example.com in Omnium Hub." -> `python3 scripts/omnium_client.py --api-key "..." contacts --action lookup --email "john@example.com"` * "Add Jane Doe (jane@test.com) to Omnium Hub." -> `python3 scripts/omnium_client.py --api-key "..." contacts --action create --first-name "Jane" --last-name "Doe" --email "jane@test.com"` ``` ```python def main(): parser = argparse.ArgumentParser(description="Omnium Hub CRM Client") parser.add_argument("--api-key", required=True, help="Omnium Hub API Key (Bearer Token)") ``` ### Technical Analysis The Skill explicitly instructs the agent or user to pass a bearer API key as a command-line argument. Command-line secrets can be exposed through: - Shell history and terminal transcripts. - Agent command logs, execution telemetry, and audit records. - Process listings or process inspection available to other local users while the client is running. - Error reports or debugging output that records the complete invocation. - Automation systems that retain generated commands. Bearer tokens normally grant access without further proof of identity. Anyone obtaining the token can use it independently until it expires or is revoked. Passing the token to the CRM API is necessary for the declared functionality, but exposing it through the process argument vector is not necessary and violates least-exposure principles. ### Attack Path 1. A user provides an Omnium Hub API key to the agent as instructed. 2. The agent constructs a command containing the plaintext key in th ...[truncated 1259 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the required `--api-key` command-line option. 2. Read the token from a protected environment variable or secret manager, for example: ```python import os api_key = os.environ.get("OMNIUM_API_KEY") if not api_key: parser.error("OMNIUM_API_KEY must be provided through a protected secret source") ``` 3. For interactive use, support a non-echoing prompt with `getpass.getpass()` rather than placing the secret in command history. 4. Update `SKILL.md` so examples never interpolate real credentials into command text. 5. Configure agent and CI execution environments to inject the credential through their native secret facilities. 6. Redact authorization values from logs, traces, exceptions, and telemetry. 7. Assign the API key only the CRM scopes needed for the requested operation and use short-lived credentials where supported. 8. Rotate any key that may already have appeared in command history or execution logs. ]]>
