T09 · Insecure Skill Coding Practices
- Location
scripts/setup-crons.js:939- Finding
Stored Command Injection Through Custom Podcast Style Names
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is mostly aligned with podcast briefing generation, but it has review-worthy risks around undisclosed data sent to a remote API, plaintext credential persistence, scheduled task setup, and unsafe command construction.
Review this skill carefully before installing. Use a temporary or manually managed API key rather than letting the wizard write it to your shell profile, inspect dry-run output with the understanding that cover-image context is not shown there, avoid scheduling custom style names containing shell metacharacters, and only enable cron jobs if you accept recurring transmission of workspace-derived briefing data to Superlore.
scripts/setup-crons.js:939Stored Command Injection Through Custom Podcast Style Names
scripts/setup-crons.js:257Shell Startup Injection and Plaintext API Key Persistence
scripts/generate-episode.js:925Undeclared Identity File Collection and Remote Disclosure
The skill performs higher-risk operations beyond its headline purpose, including email-based OTP login/API key creation with an external service, writing secrets to shell rc files, and optionally installing cron jobs. These actions affect authentication, secret persistence, and long-lived execution; if users are not clearly informed, they may unintentionally create durable access or background tasks that continue sending summarized workspace data off-host.
The skill performs higher-risk operations beyond its headline purpose, including email-based OTP login/API key creation with an external service, writing secrets to shell rc files, and optionally installing cron jobs. These actions affect authentication, secret persistence, and long-lived execution; if users are not clearly informed, they may unintentionally create durable access or background tasks that continue sending summarized workspace data off-host.
Referenced artifact was not completely inspected
node scripts/setup-crons.js
Referenced artifact was not completely inspected
node scripts/setup-crons.js
Referenced artifact was not completely inspected
node scripts/setup-crons.js
Referenced artifact was not completely inspected
node scripts/generate-episode.js # Your first episode in 2 minutes
Referenced artifact was not completely inspected
node scripts/generate-episode.js # Your first episode in 2 minutes
Referenced artifact was not completely inspected
node scripts/generate-episode.js # Your first episode in 2 minutes
Referenced artifact was not completely inspected
node scripts/generate-episode.js # Your first episode in 2 minutes
Referenced artifact was not completely inspected
node scripts/generate-episode.js # Your first episode in 2 minutes
Referenced artifact was not completely inspected
node scripts/generate-episode.js # Your first episode in 2 minutes
Referenced artifact was not completely inspected
node scripts/generate-episode.js # Your first episode in 2 minutes
Referenced artifact was not completely inspected
node scripts/generate-episode.js # Your first episode in 2 minutes
Referenced artifact was not completely inspected
node scripts/generate-episode.js # Your first episode in 2 minutes
Referenced artifact was not completely inspected
node scripts/generate-episode.js # Your first episode in 2 minutes
The privacy comments claim sensitive data never leaves the machine and raw files are never transmitted, but generateCoverImagePrompt reads identity files directly and includes extracted project descriptors in coverImagePrompt sent to the remote API. Because that path is unsanitized and contradicts the privacy guarantee, users may unknowingly exfiltrate personal or proprietary context under a false assurance of safety.
Without declared permissions the skill's intent is opaque and cannot be validated.
The documentation explicitly encourages putting detailed personal briefing data into the topic field and sending it to a third-party API, while also suggesting an analytics identifier header, but it does not clearly warn users about privacy, retention, or third-party access implications. In the context of an agent skill that connects to workspace memory and files, this materially increases the risk of unintentional exfiltration of sensitive internal data to an external service.
The script reads ~/.openclaw/workspace/IDENTITY.md, USER.md, and SOUL.md outside the discovered workspace and uses extracted text to build coverImagePrompt, which is then sent to the external Superlore API. This bypasses the file-scoping users would reasonably expect and expands data collection to global identity files that are not passed through the documented sanitization pipeline.
The request body explicitly sets language: 'en', which forces English output regardless of user preference. The file does not present this as an opt-in choice or document a justified region-specific constraint, so it conflicts with the language/locale policy requirement.
This is a credential session-persistence issue: the script stores an API key in shell profile files so every future shell session exports the secret automatically. Persisting secrets this way broadens exposure across the system and increases the blast radius if another tool, process, or user account can read the profile or inherited environment.
// ─────────────────────────────────────────────────────────────────────────────
/**
* Write an API key export line to the user's shell profile (~/.zshrc or ~/.bashrc).
*/
function saveToShellProfile(apiKey) {
const shell = process.env.SHELL || '';
The wizard offers to append SUPERLORE_API_KEY directly into ~/.zshrc or ~/.bashrc, creating long-lived credential persistence in plaintext. This expands the skill's reach from one-time podcast setup into modifying the user's login environment, and exposes the key to local compromise, accidental disclosure, shell-history/debug output, backups, and unrelated processes inheriting the environment.
The manifest says the skill can schedule morning, midday, or evening briefings, and outputting commands would fit that purpose. However, actually executing openclaw cron add through a subprocess crosses into direct system/task configuration, which is a stronger capability than the user-facing description of transforming a workspace into briefings.
Detected: suspicious.dangerous_exec