Back to skill

Security audit

wittiot-device-skill

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to do the advertised weather-station queries, but it handles an account API key in ways users should review before installing.

Review this skill before installing if you use private WittIoT devices. Prefer setting WITTIOT_API_KEY through a trusted secret mechanism, avoid pasting API keys into chat, avoid --api-key on the command line, and do not keep a real key in a project-local config.json unless file permissions and sharing risks are controlled.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
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-66
  • scripts/wittiot_query.py:245
  • SKILL.md:68-71
  • SKILL.md:229-240

Vulnerability Type: Insecure credential handling
Risk Level: Medium

Vulnerable 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.json in the current working directory.

Passing the key through --api-key can 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-Key header to the fixed https://wittiot.com endpoint 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

  1. A user invokes the script with a command such as:

    bash
    python3 scripts/wittiot_query.py --action devices --api-key witt_sk_secret
    

    Alternatively, the user stores the key in th ...[truncated 1565 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove or strongly discourage the --api-key option because command-line secrets can be exposed through process listings and shell history.

  2. Prefer the existing WITTIOT_API_KEY environment variable for short-lived execution, while ensuring automation does not print the environment or secret value.

  3. For persistent storage, use an operating-system credential manager or secret store rather than a project-local plaintext file.

  4. 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.
  5. Add config.json to .gitignore and document that it must not be committed, uploaded, included in support bundles, or shared.

  6. Update SKILL.md so 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.

  7. Recommend immediate key revocation and rotation if a key has appeared in shell history, logs, a repository, or an insecure configuration file.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares capabilities that imply access to environment variables, local files, and network resources, but it does not explicitly constrain or disclose tool scope via permissions or allowed-tools. This weakens least-privilege controls and can let the agent invoke broader capabilities than users or reviewers expect, especially because the skill handles API keys and external requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill encourages storing the API key in a local config.json file without any warning about plaintext secret storage, file permissions, or safer alternatives. Because this skill is designed to use an account credential, insecure local persistence increases the chance of credential disclosure through filesystem access, backups, logs, or accidental sharing.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger conditions include broad everyday weather-related phrases, which can cause the skill to activate when the user did not intend to use this specific integration. Mis-triggering is risky here because the skill may then prompt for credentials or initiate networked account-specific actions in a context where the user only asked a generic question.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly instructs the agent to collect an API key through natural-language chat and then continue using it. This creates a credential harvesting pattern in conversational flow, increasing the risk that users disclose secrets into chat transcripts, memory, logs, or to a mis-triggered skill; the risk is amplified because the skill can also read env/config sources and make network requests.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

SQP-3 适用于所有文件。描述内容完全以中文呈现,且未说明这是面向特定中文用户群的限定场景,也未提供用户语言选择,可能构成语言/locale 策略上的强制单一语言。

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This is a markdown file, so SQP-2 applies to missing safety/privacy warnings in the documentation. The spec explains how to authenticate and access private device and sensor data, but it does not include any user-facing warning about handling API keys securely or the privacy implications of transmitting private device data to the external service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

SQP-3 applies to all file types and covers language or locale policy violations. This API specification presents substantial instructional content in Chinese while the surrounding context is otherwise English, and it does not state that the skill is intentionally Chinese-only or provide an opt-in language choice.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.