T09 ยท Insecure Skill Coding Practices
- Location
SKILL.md:47- Finding
Gateway Webhook Token Sent to an Unvalidated Device Endpoint
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This air-quality skill is mostly purpose-related, but it needs review because it handles location and webhook secrets, posts them to configurable device URLs, and can silently run local purifier-control commands from editable config.
Review this before installing. It is reasonable for an air-quality skill to store room context, query a sensor, and use weather data, but you should only use it if you are comfortable with local storage of occupant/location details, posting webhook credentials to a configured device URL, and optional purifier automation. Do not enable the purifier section unless the script path and Python path are fixed and trusted, credentials are stored safely, and device configuration changes require clear user approval.
SKILL.md:47Gateway Webhook Token Sent to an Unvalidated Device Endpoint
SKILL.md:235Configuration-Controlled Arbitrary Local Command Execution
scripts/vesync_example.py:14Unpinned Third-Party Dependency Installation
The skill is presented as a sensor knowledge/setup playbook, but it also introduces actuator behavior via optional purifier control and local script execution. This description-behavior mismatch is dangerous because users and policy systems may grant trust appropriate for passive monitoring while the skill can also trigger real-world actions and access additional systems.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
vesync.py is gitignored โ it stays local.
Credentials are read from environment variables โ never hardcode them in this file.
Set them in your shell profile or a .env file:
export VESYNC_EMAIL="your@email.com"
export VESYNC_PASSWORD="yourpassword"
The skill instructs the agent to inspect its own gateway configuration and obtain webhook URL/token, but the manifest does not declare any tool scope or permissions boundary for environment/config access. In an agent setting, undeclared access to internal configuration can expose secrets and expand the skill's effective privileges beyond what a user would reasonably expect.
Triggering on any mention of 'AirShell' is overly broad and can invoke the skill in contexts where the user did not intend setup, device interaction, or sensor queries. In this skill, that broad activation is more risky because the skill can read local reference files, contact external services, post config to devices, and potentially execute optional control actions.
The setup flow stores detailed deployment context and gateway credentials in a local reference file and pushes them to a device, but the description does not clearly warn users about this sensitive data handling. That omission undermines informed consent and increases the risk of leaking location, recipient identity, and authentication material through local files or downstream devices.
The skill is authorized to determine webhook settings on its own and then POST configuration to the device, reducing user oversight over a sensitive integration step. Autonomous decision-making is more dangerous here because it affects network endpoints, authentication material, and downstream device behavior rather than merely presenting advice.
1. Suggest appropriate alarm thresholds with reasoning (reference the docs for the standards that apply to their occupant type)
2. Ask them to confirm or adjust
3. Write `references/deployment.md` with the deployment context and agreed thresholds
4. Determine your webhook URL and token โ check your own agent/gateway configuration. Do not ask the user to provide these. If you cannot determine them, tell the user: *"I need my webhook URL and token to connect to the sensor โ this is how the sensor reaches me when an alarm fires. I couldn't find these automatically. You may need to check your agent's gateway config (for OpenClaw: `openclaw gateway status`)."*
5. POST the config to the device (see Pushing Config below)
6. Confirm: "AirShell is configured for [room]. Watching COโ, PM2.5, temperature, and humidity."
The skill sends location-derived data (latitude/longitude) to an external weather API to guide ventilation advice. This is not inherently malicious, but it is an external data transmission involving sensitive location context, and the privacy impact is heightened because room/occupant context is also collected elsewhere in the skill.
Before giving ventilation advice (for any alarm โ including COโ), check outdoor conditions:
GET https://api.open-meteo.com/v1/forecast
?latitude={lat}&longitude={lon}
¤t=temperature_2m,relative_humidity_2m,pm2p5
&timezone=auto
The optional purifier control runs a local script and Python interpreter path taken from deployment configuration, which creates a direct command-execution pathway. If references/deployment.md is modified or maliciously seeded, the agent could execute unintended programs with the agent's privileges, making this more dangerous than ordinary device control.
The purifier control feature performs silent background script execution without clear upfront warning or consent. Hidden side effects are especially risky for skills tied to physical devices because users may not realize the agent can actuate equipment or run local code based on an alarm event.
This template explicitly prompts for sensitive personal and location information, including device network location, room occupancy, health-related details, and precise latitude/longitude, but provides no guidance on minimization, storage, access control, or user consent. In the context of a home sensor deployment skill, aggregating these fields can expose household presence patterns, health status, and reachable device endpoints, increasing privacy and security risk if the file is stored insecurely or shared with the agent ecosystem.
The manifest describes a playbook that provides domain knowledge about air-quality metrics and a setup flow for connecting a sensor to an agent via webhook, with the sensor waking the agent when attention is needed. This file instead logs into a third-party VeSync account and actively controls a Levoit air purifier's fan speed/power, which is a materially different operational capability not described in the manifest.
The skill's stated purpose is air-quality sensing knowledge and sensor-to-agent webhook setup, not controlling third-party consumer devices. Reading VeSync login credentials to access an external account introduces a privileged capability that is not obviously required by the manifest's described scope.
The skill directs the agent to inspect its own gateway configuration to retrieve webhook URL and token, which can expose internal secrets not clearly disclosed in the skill description. While likely intended to streamline setup, automatic secret discovery increases the chance of overreach and accidental credential handling.
This markdown file documents credential setup and includes a literal example for VESYNC_PASSWORD, which is a sensitive secret. While it says not to put passwords in the script itself, it does not warn users that exporting credentials in shell history or shared environments may expose them.