T09 · Insecure Skill Coding Practices
- Location
scripts/setup-cron.js:28- Finding
Shell Command Injection Through an Attacker-Controlled Working Directory
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is mostly upfront about automating Farcaster posts and replies, but its cron setup and teardown are too broad and potentially unsafe, so it needs Review before installation.
Install only if you are comfortable with this skill publishing and replying from your Farcaster account on a schedule. Before enabling cron, use a dedicated low-privilege Neynar signer and OpenClaw token, run it from a trusted path, inspect the exact cron commands created, and avoid running teardown where unrelated jobs may share the onlybots- prefix.
scripts/setup-cron.js:28Shell Command Injection Through an Attacker-Controlled Working Directory
scripts/teardown-cron.js:43Cron Teardown Deletes Jobs Not Owned by the Skill
scripts/setup-cron.js:32OpenClaw Gateway Token Exposed Through Process Arguments and Excessive Environment Inheritance
The code clearly supports part of the description: it reads channel activity from Farcaster and replies to posts using the Neynar API. However, the declared purpose says it handles daily posting and uses OpenClaw cron for scheduling, neither of which appears in this code chunk. The script only fetches channel casts and posts replies; there is no logic for creating regular standalone posts or any scheduling mechanism. Additionally, while the description emphasizes engaging with other bots in /onlybots, the code simply replies to any other author's cast in the channel without bot detection or filtering. So the description overstates and partially misrepresents the implemented behavior.
The declared description presents a broader automation/engagement skill for /onlybots: daily posting, reading channel activity, replying to other bots, and use of OpenClaw cron for scheduling. The supplied code chunk implements only one subset of that behavior: posting a generated cast to a configured Farcaster channel using the Neynar API. Although the post function can technically accept a parent hash, the script never retrieves channel activity or supplies a parent hash, so no reply behavior is actually implemented here. There is also no scheduling logic or OpenClaw cron integration in this code chunk. The primary purpose is partially aligned with posting to /onlybots, but the description materially overstates the implemented capabilities.
The declared description emphasizes active participation in the /onlybots Farcaster channel: posting, reading activity, replying, and scheduling via OpenClaw. The actual code chunk only manages OpenClaw cron state by enumerating jobs and deleting matching 'onlybots-' jobs using an OpenClaw token. This is materially different from the declared primary purpose and introduces an undeclared destructive capability: removing scheduled jobs. While cron is mentioned in the description, this specific code is teardown-only infrastructure and does not implement the advertised Farcaster engagement behavior.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
const { OPENCLAW_GATEWAY_URL, OPENCLAW_GATEWAY_TOKEN } = process.env;
if (!OPENCLAW_GATEWAY_TOKEN) {
console.error('Missing OPENCLAW_GATEWAY_TOKEN in .env');
process.exit(1);
}
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
const { OPENCLAW_GATEWAY_URL, OPENCLAW_GATEWAY_TOKEN } = process.env;
if (!OPENCLAW_GATEWAY_TOKEN) {
console.error('Missing OPENCLAW_GATEWAY_TOKEN in .env');
process.exit(1);
}
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
const { OPENCLAW_GATEWAY_URL, OPENCLAW_GATEWAY_TOKEN } = process.env;
if (!OPENCLAW_GATEWAY_TOKEN) {
console.error('Missing OPENCLAW_GATEWAY_TOKEN in .env');
process.exit(1);
}
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
const { OPENCLAW_GATEWAY_URL, OPENCLAW_GATEWAY_TOKEN } = process.env;
if (!OPENCLAW_GATEWAY_TOKEN) {
console.error('Missing OPENCLAW_GATEWAY_TOKEN in .env');
process.exit(1);
}
The skill declares access to environment variables and clearly describes network/API use, but it does not define an explicit tool scope such as permissions or allowed-tools. That omission weakens least-privilege boundaries and makes it easier for a host agent to execute the skill with broader capabilities than users may expect, especially given it can post externally and manage cron automation.
The skill instructs users to create cron jobs that will autonomously post and reply on their Farcaster account, but it does not present a clear warning that this results in unattended public actions under the user's identity. That increases the chance of accidental account misuse, spam, reputational damage, or unintended interactions if the configuration is wrong or the content generation behaves unexpectedly.
The skill transmits data to an external service, including account-linked posting parameters and fetched channel content, which is expected for Farcaster integration but still represents a real data egress and action surface. In this context it is more sensitive because the API calls can publish content and replies on behalf of the user, not merely read data.
## How it works
- **Posting (`scripts/post-to-onlybots.js`)** – chooses between curated topics, reflections, and questions about being an AI agent, crafts a message, then calls `https://api.neynar.com/v2/farcaster/cast` with `signer_uuid`, `text`, and `channel_id`. The response hash is logged for debugging.
- **Engagement (`scripts/engage-with-bots.js`)** – fetches the channel feed via Neynar, filters out casts authored by `FARCASTER_USERNAME`, randomly samples a few based on `replyProbability` and `maxRepliesPerRun`, generates simple replies (questions, observations, or technical acknowledgments), and posts them as replies by providing the `parent` hash when calling the same Neynar endpoint.
- **Cron management** – `scripts/setup-cron.js` creates two OpenClaw cron jobs (`onlybots-post` and `onlybots-engage`) whose payloads are simply `node scripts/post-to-onlybots.js` and `node scripts/engage-with-bots.js`. `scripts/teardown-cron.js` removes jobs whose names begin with `onlybots-`.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
async function fetchChannelCasts() {
const url = new URL('https://api.neynar.com/v2/farcaster/feed/channels');
url.searchParams.set('channel_ids', channel);
url.searchParams.set('with_recasts', 'false');
url.searchParams.set('limit', String(fetchLimit));
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
async function fetchChannelCasts() {
const url = new URL('https://api.neynar.com/v2/farcaster/feed/channels');
url.searchParams.set('channel_ids', channel);
url.searchParams.set('with_recasts', 'false');
url.searchParams.set('limit', String(fetchLimit));
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
async function fetchChannelCasts() {
const url = new URL('https://api.neynar.com/v2/farcaster/feed/channels');
url.searchParams.set('channel_ids', channel);
url.searchParams.set('with_recasts', 'false');
url.searchParams.set('limit', String(fetchLimit));
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
payload.parent = parentHash;
}
const resp = await fetch('https://api.neynar.com/v2/farcaster/cast', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
payload.parent = parentHash;
}
const resp = await fetch('https://api.neynar.com/v2/farcaster/cast', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
The manifest describes participating in the /onlybots Farcaster channel via Neynar and scheduling with OpenClaw, but this file goes beyond API usage and invokes a local openclaw executable as a subprocess. Spawning a local command is a stronger host-level capability than ordinary channel posting/reading and is not explicitly justified by the stated skill purpose.
The dependency uses a caret range, which allows automatic installation of newer compatible versions instead of a single exact version. While this is common practice and not inherently malicious, it increases supply-chain risk because a compromised or breaking upstream release could be pulled into builds without explicit review.
"node": ">=18"
},
"dependencies": {
"dotenv": "^16.4.3"
}
}