T09 · Insecure Skill Coding Practices
- Location
scripts/wittiot_query.py:61- Finding
API Key Exposure Through Plaintext Configuration and Command-Line Arguments
- Content
View full analysis
Vulnerability Details
File Locations:
scripts/wittiot_query.py:61-66scripts/wittiot_query.py:245SKILL.md:68-71SKILL.md:229-240
Vulnerability Type: Insecure credential handling
Risk Level: MediumVulnerable Code:
python def load_config() -> Dict[str, Any]: path = os.path.join(os.getcwd(), "config.json") if os.path.exists(path): with open(path, "r", encoding="utf-8") as f: return json.load(f) return {}python parser.add_argument("--api-key", default=None, help="WittIoT API Key (witt_sk_xxxx)")The documented plaintext configuration format is:
json { "apiKey": "witt_sk_your_api_key_here" }Technical Analysis
The Skill accepts a sensitive WittIoT API key through a command-line argument or a predictable plaintext file named
config.jsonin the current working directory.Passing the key through
--api-keycan expose it through:- Shell command history
- Process listings available to other local users or processes
- Process-monitoring and diagnostic tools
- Terminal logs and automation logs
The configuration loader reads the key from plaintext without verifying ownership, file type, or restrictive permissions. A configuration file readable by other users, included in a repository, copied into a backup, or collected in a support bundle can disclose the credential.
Sending the API key in the
X-API-Keyheader to the fixedhttps://wittiot.comendpoint is necessary for the declared authenticated query functionality and does not, by itself, constitute unauthorized exfiltration. The identified weakness concerns how the credential is supplied and stored before transmission.Attack Path
-
A user invokes the script with a command such as:
bash python3 scripts/wittiot_query.py --action devices --api-key witt_sk_secretAlternatively, the user stores the key in th ...[truncated 1565 chars]
- Remediation
View remediation
Remediation Suggestions
-
Remove or strongly discourage the
--api-keyoption because command-line secrets can be exposed through process listings and shell history. -
Prefer the existing
WITTIOT_API_KEYenvironment variable for short-lived execution, while ensuring automation does not print the environment or secret value. -
For persistent storage, use an operating-system credential manager or secret store rather than a project-local plaintext file.
-
If file-based configuration must remain:
- Store it in a user-specific configuration directory rather than the current working directory.
- Create it with mode
0600. - Verify that it is a regular file owned by the current user.
- Reject or prominently warn about group-readable or world-readable permissions.
- Avoid following untrusted symbolic links.
- Never print the key in normal or error output.
-
Add
config.jsonto.gitignoreand document that it must not be committed, uploaded, included in support bundles, or shared. -
Update
SKILL.mdso its credential-handling instructions match the implementation. It currently refers to automatically prompting for and saving a key, while the reviewed script implements neither behavior. -
Recommend immediate key revocation and rotation if a key has appeared in shell history, logs, a repository, or an insecure configuration file.
-
