T09 · Insecure Skill Coding Practices
- Location
scripts/parser.py:104- Finding
Sensitive transcript arguments and error output are retained in plaintext
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This observability skill is mostly coherent, but it needs review because it broadly reads local agent transcripts and can retain or send sensitive excerpts with weak controls.
Review before installing in environments where agent transcripts may contain secrets, customer data, or sensitive file paths. Keep the dashboard bound to localhost, avoid configuring external webhooks unless the destination is trusted, do not commit config.yaml after adding a webhook, and consider adding redaction-before-storage, dependency locks, retention limits, owner-only file permissions, and local bundled frontend assets.
scripts/parser.py:104Sensitive transcript arguments and error output are retained in plaintext
scripts/alerts/discord_alerter.py:16Incomplete redaction and unrestricted webhook destinations can disclose failure data externally
dashboard/frontend/index.html:7Dashboard executes third-party JavaScript without integrity verification
The declared description presents a broad observability system with monitoring, usage/cost accounting, anomaly detection, alerts, and a dashboard. The supplied code chunk does not perform any of those core functions. Instead, it is a narrow helper that redacts API keys, tokens, webhook URLs, and the local home directory from alert payload text/details. While sanitizing alerts could support an observability/alerting system, this chunk’s actual behavior is materially different from the declared primary purpose and covers only a small auxiliary piece of it.
The declared description presents a full observability capability with monitoring, usage/cost accounting, anomaly detection, alerting, and dashboarding. The supplied code chunk instead implements a narrow helper utility for sanitizing alert payloads. While alert sanitization could be a supporting component of an observability/alerting system, this chunk does not itself perform the core declared functions. Therefore, the code behavior is materially narrower and different from the declared primary purpose.
Package name closely resembles a popular package, suggesting possible typosquatting. Attackers publish malicious packages with similar names to trick developers into installing them.
The skill advertises executable commands that read local transcripts, write to a SQLite database, and can send alerts to external destinations, yet it declares no explicit tool scope or permission boundaries. In an agent environment, missing scope declarations can cause over-broad access and make reviewers or policy engines unable to constrain file and network operations appropriately.
The manifest describes a monitoring and observability skill with alerts and dashboarding, which implies collecting, analyzing, and reporting telemetry. The configure-alerts command goes beyond monitoring by persisting new configuration to disk, changing the skill's runtime setup rather than just observing or reporting state.
The code persists a sensitive Discord webhook URL to config.yaml in plaintext without any warning, consent prompt, or permissions hardening. If the file is later read by other local users, included in backups, committed to source control, or exposed through logs/support bundles, the webhook can be abused to send fraudulent alerts, spam a Discord channel, or interfere with incident-response trust.
This code sends alert content and details to an external Discord webhook via HTTP POST, which can transmit user or system data off-host. The file contains no confirmation prompt, user-facing notice, or explanatory comment/docstring describing that alert contents will be sent to Discord.
The manifest describes this skill as agent observability that monitors invocations, costs, anomalies, alerts, and a dashboard. While alerting itself is in scope, this command persistently rewrites the skill's configuration file to store a Discord webhook URL, which is administrative configuration management rather than monitoring behavior.
The code persists a Discord webhook URL directly into config.yaml without warning the user that this value is effectively a credential and may grant unauthorized message posting if exposed. Storing it in plaintext on disk increases the risk of accidental disclosure through backups, source control, file sharing, or permissive filesystem access.
Observability and alert delivery can justify sending notifications, but storing arbitrary webhook endpoints supplied at runtime introduces configuration/secrets handling behavior beyond passive monitoring. This is a distinct capability from collecting metrics and detecting anomalies, and it is not explicitly reflected in the manifest text.
The parser defaults to reading transcripts from ~/.openclaw/agents, which can contain sensitive prompts, tool inputs/outputs, credentials, or other user data, yet the code provides no consent gate, disclosure, scoping control, or redaction before ingesting and emitting derived events. In an observability skill, this increases privacy risk because monitoring code may process data across all agents and sessions automatically, making accidental over-collection and downstream exposure more likely.
The dependency is specified with a lower bound only, so builds may resolve to different FastAPI versions over time. This weakens supply-chain reproducibility and can unintentionally introduce vulnerable or breaking releases into deployments.
fastapi>=0.104.0
uvicorn>=0.24.0
pyyaml>=6.0
FastAPI has known advisories in some versions, and the manifest does not pin an exact release, so it is impossible to verify whether the deployed version is affected. In a network-facing observability service, that uncertainty matters because framework flaws can be remotely reachable.
The Uvicorn dependency is unpinned, allowing package resolution to drift across environments and over time. That creates supply-chain risk because a newly published vulnerable or malicious version could be installed without any manifest change.
fastapi>=0.104.0
uvicorn>=0.24.0
pyyaml>=6.0
Uvicorn has known advisories in certain releases, but the current requirement does not identify which version will actually be installed. Since this skill appears to expose dashboard and API functionality, a vulnerable ASGI server could increase exposure to remote attacks.
PyYAML is declared with only a minimum version, so the installed version is not deterministic. Because PyYAML has a history of unsafe parsing issues, version drift increases the chance of pulling in a release with security-relevant behavior or unresolved advisories.
fastapi>=0.104.0
uvicorn>=0.24.0
pyyaml>=6.0
PyYAML has multiple historical security advisories, and without an exact version pin there is no reliable way to determine whether installs are safe. This is more concerning here because observability systems often ingest configuration and event data that may originate from external or semi-trusted sources.
The manifest mentions pluggable alerts, so sending alerts is in scope, but this file also provides credential-style configuration management by taking a webhook URL from the CLI and persisting it to config.yaml. Handling and storing integration secrets/configuration is a broader administrative capability than simple observability and is not explicitly stated in the manifest.
This code persists parser state to a file via save_state(), creating directories and writing JSON, but there is no confirmation prompt, logging, or comment/docstring warning the user that local state will be written. For a code file, file writes should have some visible disclosure unless clearly covered elsewhere.
The parser opens and reads transcript files under ~/.openclaw/agents/.../sessions/*.jsonl, which may contain user or system data, but the code provides no confirmation, visible logging, or warning comment/docstring about accessing those files. This is a data-access operation that lacks explicit disclosure in the file itself.
This code creates a data directory and opens a persistent SQLite database, which causes agent metrics to be stored on disk. In this file there is no confirmation prompt, user-facing log, or comment/docstring warning that session-related telemetry will be persisted locally.
This code creates a local data directory and opens a persistent SQLite database, then later records tool invocations, sessions, LLM calls, and alerts. The file contains no confirmation prompt, user-facing log/print, or explanatory comments/docstrings warning that operational data will be stored on disk.
No suspicious patterns detected.